蓝桥杯单片机第九届省赛编程题(深夜学习——单片机)
创始人
2024-06-01 07:52:55
0

一、根据硬件框图初始化好要使用的外设

  1. 推测出外设类型:

PCF8591、矩阵按键、AT24C02、LED、数码管(定时器)

  1. 创建工程模板:

(1)主函数:

#ifndef PBBLIC_H
#define PBBLIC_H#include #define u8 unsigned char
#define u16 unsigned intvoid Close_All();#endif

(2)公共函数:

#ifndef PBBLIC_H
#define PBBLIC_H#include #define u8 unsigned char
#define u16 unsigned intvoid Close_All();#endif
#include "Public.h"/*向某个锁存器发送信息
*/
void Select(u8 cs,u8 s_data)
{P0 = s_data;P2 = P2 & 0x1f | (cs<<5);P2 &= 0x1f;
}/*关闭无关设备
*/
void Close_All()
{//关闭蜂鸣器和继电器Select(5,0x00);//关闭LEDSelect(4,0xff);//清空数码管数据Select(7,0xff);
}
  1. LED灯:

(1)主函数:

#include "Public.h"
#include "Simple_Device.h"
void main()
{Close_All();LED_Show(0xff);
}

(2)LED函数:

#ifndef SIMPLE_DEVICE_H
#define SIMPLE_DEVICE_H#include "Public.h"void LED_Show(u8 l_data);#endif
#include "Simple_Device.h"/*根据输入的8位数显示LED,其中1为亮灯
*/
void LED_Show(u8 l_data)
{Select(4,~l_data);
}
  1. 数码管:

(1)主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
void Key_Proc();
void SEG_Proc();
void main()
{Close_All();Timer0_Init();while(1){SEG_Proc();}
}void SEG_Proc()
{if(seg_delay)return;seg_delay = 1;sprintf(COT,"%u%u",(u16)1234,(u16)5678);SEG_TSL(COT,COD);
}void Timer0_Isr(void) interrupt 1
{if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;
}

(2)数码管函数:

#ifndef SEG_H
#define SEG_H#include "Public.h"void SEG_TSL(u8 *input,u8 *output);
void SEG_Show(u8 COD,u8 PIS);
#endif
#include "SEG.h"code unsigned char Seg_Table[] = 
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};/*输入字符串输出数码管代码
*/
void SEG_TSL(u8 *input,u8 *output)
{u8 i=0;for(i=0;i<8;i++){switch(input[i]){case '0':output[i] = Seg_Table[0];break;case '1':output[i] = Seg_Table[1];break;case '2':output[i] = Seg_Table[2];break;case '3':output[i] = Seg_Table[3];break;case '4':output[i] = Seg_Table[4];break;case '5':output[i] = Seg_Table[5];break;case '6':output[i] = Seg_Table[6];break;case '7':output[i] = Seg_Table[7];break;case '8':output[i] = Seg_Table[8];break;case '9':output[i] = Seg_Table[9];break;default:output[i] = 0xff;}}
}/*数码管显示函数
*/
void SEG_Show(u8 COD,u8 PIS)
{//消隐Select(7,0xff);//位选Select(6,0x01<
  1. 矩阵按键:

(1)主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
void Key_Proc();
void SEG_Proc();
void main()
{Close_All();Timer0_Init();while(1){
//        SEG_Proc();Key_Proc();}
}void Key_Proc()
{u8 key_now,key_dwon;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_old = key_now;if(key_dwon){sprintf(COT,"%u",(u16)key_dwon);SEG_TSL(COT,COD);}
}void SEG_Proc()
{if(seg_delay)return;seg_delay = 1;sprintf(COT,"%u%u",(u16)1234,(u16)5678);SEG_TSL(COT,COD);
}void Timer0_Isr(void) interrupt 1
{if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;
}

(2)按键检测函数:

#ifndef SIMPLE_DEVICE_H
#define SIMPLE_DEVICE_H#include "Public.h"void LED_Show(u8 l_data);
u8 M_key();    
#endif
#include "Simple_Device.h"/*根据输入的8位数显示LED,其中1为亮灯
*/
void LED_Show(u8 l_data)
{Select(4,~l_data);
}/*矩阵按键检测
*/
u8 M_key()
{u16 key_temp=0,i=0;//逐个置零,读取电平P44=0;P42=1;P35=1;P34=1;key_temp |= (P3&0x0f);P44=1;P42=0;P35=1;P34=1;key_temp = (key_temp<<4) | (P3&0x0f);P44=1;P42=1;P35=0;P34=1;key_temp = (key_temp<<4) | (P3&0x0f);P44=1;P42=1;P35=1;P34=0;key_temp = (key_temp<<4) | (P3&0x0f);//检测数据for(i=0;i<16;i++){if((key_temp & (0x8000>>i)) == 0)return i+4;}return 0;
}
  1. PCF8591:

由于我常常会忘记设备地址、控制字节格式、应答信号,所以我常常会从从官方给的数据中的数据手册中获得信息:

目录:

地址:

命令字节:

应答信号:

数据与电压换算:

(1)主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
void Key_Proc();
void SEG_Proc();
void main()
{Close_All();Timer0_Init();//确定输出为AIN3PCF8591_Write(0x03);while(1){SEG_Proc();
//        Key_Proc();}
}void Key_Proc()
{u8 key_now,key_dwon;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_old = key_now;if(key_dwon){sprintf(COT,"%u",(u16)key_dwon);SEG_TSL(COT,COD);}
}void SEG_Proc()
{u8 show_cot;if(seg_delay)return;seg_delay = 1;show_cot =     PCF8591_Read();sprintf(COT,"%u",(u16)show_cot);    
//    sprintf(COT,"%u%u",(u16)1234,(u16)5678);SEG_TSL(COT,COD);
}void Timer0_Isr(void) interrupt 1
{if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;
}

(2)PCF8591函数

#ifndef PCF8591_H
#define PCF8591_H#include "Public.h"
#include "iic.h"void PCF8591_Write(u8 c_data);
u8 PCF8591_Read();
#endif
#include "PCF8591.h"/*写入控制字节
*/
void PCF8591_Write(u8 c_data)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(c_data);IIC_WaitAck();IIC_Stop();
}/*读取数据字节
*/
u8 PCF8591_Read()
{u8 d_data;IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();d_data = IIC_RecByte();IIC_SendAck(1);IIC_Stop();    return d_data;
}

(3)官方给的IIC驱动文件:

#ifndef _IIC_H
#define _IIC_H#include "Public.h"
#include "intrins.h"sbit SDA = P2^1;
sbit SCL = P2^0;void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); #endif
#include "iic.h"#define DELAY_TIME 5//
void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);        
}//
void IIC_Start(void)
{SDA = 1;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 0;IIC_Delay(DELAY_TIME);SCL = 0;    
}//
void IIC_Stop(void)
{SDA = 0;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 1;IIC_Delay(DELAY_TIME);
}//
void IIC_SendAck(bit ackbit)
{SCL = 0;SDA = ackbit;                      IIC_Delay(DELAY_TIME);SCL = 1;IIC_Delay(DELAY_TIME);SCL = 0; SDA = 1;IIC_Delay(DELAY_TIME);
}//
bit IIC_WaitAck(void)
{bit ackbit;SCL  = 1;IIC_Delay(DELAY_TIME);ackbit = SDA;SCL = 0;IIC_Delay(DELAY_TIME);return ackbit;
}//
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){SCL  = 0;IIC_Delay(DELAY_TIME);if(byt & 0x80) SDA  = 1;else SDA  = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL  = 0;  
}//
unsigned char IIC_RecByte(void)
{unsigned char i, da;for(i=0; i<8; i++){   SCL = 1;IIC_Delay(DELAY_TIME);da <<= 1;if(SDA) da |= 1;SCL = 0;IIC_Delay(DELAY_TIME);}return da;    
}
  1. AT24C02:

设备地址:

写操作:

读操作:

(1)主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
#include "AT24C02.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
void Key_Proc();
void SEG_Proc();
void main()
{Close_All();Timer0_Init();while(1){SEG_Proc();
//        Key_Proc();}
}void Key_Proc()
{u8 key_now,key_dwon;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_old = key_now;if(key_dwon){sprintf(COT,"%u",(u16)key_dwon);SEG_TSL(COT,COD);}
}
void Delay5ms()        //@12MHz
{unsigned char i, j;i = 59;j = 90;do{while (--j);} while (--i);
}void SEG_Proc()
{static u8 num=0;u8 show_cot;if(seg_delay)return;seg_delay = 1;AT24C02_Write(0x01,num);Delay5ms();    show_cot = AT24C02_Read(0x01);sprintf(COT,"%u",(u16)show_cot);    
//    sprintf(COT,"%u%u",(u16)1234,(u16)5678);SEG_TSL(COT,COD);num++;
}void Timer0_Isr(void) interrupt 1
{if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;
}

(2)AT24C02函数:

#ifndef AT24C02_H
#define AT24C02_H#include "Public.h"
#include "iic.h"void AT24C02_Write(u8 w_addr,u8 w_data);
u8 AT24C02_Read(u8 r_addr);#endif
#include "AT24C02.h"void AT24C02_Write(u8 w_addr,u8 w_data)
{IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(w_addr);IIC_WaitAck();IIC_SendByte(w_data);IIC_WaitAck();    IIC_Stop();
}u8 AT24C02_Read(u8 r_addr)
{u8 r_data;IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(r_addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0xa1);IIC_WaitAck();r_data = IIC_RecByte();IIC_SendAck(1);    IIC_Stop();return r_data;
}

二、实现功能:

由于我们是靠按键改变模式的,所以我们可以从按键函数出发,补充各种功能。

  1. 基本功能框架:

按键可以分为两种:功能按键和切换按键,搭建框架则要抓住切换按键。

由上面两图我们可以知道,显示模式分为非显示模式、设置模式和亮度显示模式,其中设置模式又分为三种状态。

(1)部分主函数:

void main()
{Close_All();Timer0_Init();while(1){
//        SEG_Proc();Key_Proc();LED_Show(0x01<<(set_mode+5));}
}void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = ~key_now & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){}else if(key_dwon == 6){if(++set_mode == 3)set_mode = 0;LED_Show(0x01<<(set_mode+5));}else if(key_dwon == 5){}    else if(key_dwon == 4){if(set_mode == 0){seg_mode = 1;LED_Show(seg_mode);}}else if(key_up == 4)    {if(set_mode == 0){seg_mode = 0;LED_Show(seg_mode);}}
}
  1. 非设置模式:

(1)部分主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
#include "AT24C02.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
//模式
u8 seg_mode,set_mode;
//非设置模式
u16 led_time=400,l_count_ms,p_count_ms;
u8 l_data,l_power=1,led_mode,turn_sign=1;void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = ~key_now & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){turn_sign ^= 1;}else if(key_dwon == 6){if(++set_mode == 3){set_mode = 0;seg_mode = 0;}elseseg_mode = 1;}else if(key_dwon == 5){}    else if(key_dwon == 4){if(set_mode == 0){seg_mode = 2;}}else if(key_up == 4)    {if(set_mode == 0){seg_mode = 0;}}}void SEG_Proc()
{u8 show_cot;if(seg_delay)return;seg_delay = 1;//非设置模式,数码管不显示任何东西if(seg_mode == 0){sprintf(COT,"");    PCF8591_Proc();}//    sprintf(COT,"%u   %u",(u16)l_power,(u16)l_temp);SEG_TSL(COT,COD);}void Timer0_Isr(void) interrupt 1
{l_count_ms++;p_count_ms++;if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;if(set_mode == 0){if(p_count_ms < 10*0.25*l_power)LED_Show(l_data);    elseLED_Show(0x00);if(p_count_ms == 10)p_count_ms = 0;}elseLED_Show(0x00);
}void LED_Proc()
{static u8 led_temp;if(l_count_ms < led_time || !turn_sign )return;l_count_ms = 0;if(led_mode == 0){l_data = 0x01<>led_temp; led_temp++;if(led_temp == 8){led_temp = 0;led_mode = 2;}}else if(led_mode == 2){l_data = (0x80>>led_temp) | (0x01<>led_temp) | (0x10<
  1. 亮度显示模式:

(1)部分主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
#include "AT24C02.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
//模式
u8 seg_mode,set_mode;
//非设置模式
u16 led_time=400,l_count_ms,p_count_ms;
u8 l_data,l_power=1,led_mode,turn_sign=1;void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = (~key_now) & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){turn_sign ^= 1;}else if(key_dwon == 6){if(++set_mode == 3){set_mode = 0;seg_mode = 0;}elseseg_mode = 1;}else if(key_dwon == 5){}    else if(key_dwon == 4){if(seg_mode == 0){seg_mode = 2;}}else if(key_up == 4)    {if(seg_mode == 2){seg_mode = 0;}}}void SEG_Proc()
{u8 show_cot;if(seg_delay)return;seg_delay = 1;//非设置模式,数码管不显示任何东西if(seg_mode == 0){sprintf(COT,"        ");    }if(seg_mode == 2){sprintf(COT,"      %02u",(u16)l_power);}
//    sprintf(COT,"%u   %u",(u16)l_power,(u16)l_temp);SEG_TSL(COT,COD);}void Timer0_Isr(void) interrupt 1
{l_count_ms++;p_count_ms++;if(++key_delay == 10)key_delay = 0;if(++seg_delay == 500)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;if(set_mode == 0){PCF8591_Proc();if(p_count_ms < 10*0.25*l_power)LED_Show(l_data);    elseLED_Show(0x00);if(p_count_ms == 10)p_count_ms = 0;}elseLED_Show(0x00);
}void LED_Proc()
{static u8 led_temp;if(l_count_ms < led_time || !turn_sign )return;l_count_ms = 0;if(led_mode == 0){l_data = 0x01<>led_temp; led_temp++;if(led_temp == 8){led_temp = 0;led_mode = 2;}}else if(led_mode == 2){l_data = (0x80>>led_temp) | (0x01<>led_temp) | (0x10<
  1. 设置模式:

(1)部分主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
#include "AT24C02.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
//模式
u8 seg_mode,set_mode;
//非设置模式
u16 led_time=400,l_count_ms,p_count_ms;
u8 l_data,l_power=1,led_mode=1,turn_sign=1;
u8 flash_sign , led_temp;void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = (~key_now) & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){turn_sign ^= 1;}else if(key_dwon == 6){if(++set_mode == 3){set_mode = 0;seg_mode = 0;//重新计数l_count_ms = 0;p_count_ms = 0;//闪烁标志更新flash_sign = 0;l_data = 0;led_temp = 0;}elseseg_mode = 1;}else if(key_dwon == 5){switch(set_mode){case 1:led_mode++;break;case 2:led_time+=100;break;            }//上边界属性if(led_mode == 5)led_mode = 1;if(led_time == 1300)led_time = 400;}    else if(key_dwon == 4){if(seg_mode == 0){seg_mode = 2;}switch(set_mode){case 1:led_mode--;break;case 2:led_time-=100;break;            }//下边界属性if(led_mode == 0)led_mode = 4;if(led_time == 300)led_time = 1200;}else if(key_up == 4)    {if(seg_mode == 2){seg_mode = 0;}}}void SEG_Proc()
{if(seg_delay)return;seg_delay = 1;//非设置模式,数码管不显示任何东西if(seg_mode == 0){sprintf(COT,"        ");    }if(seg_mode == 1){if(set_mode == 1 && flash_sign == 1){sprintf(COT,"    %4u",(u16)led_time);flash_sign = 0;}else if(set_mode == 2 && flash_sign == 1){sprintf(COT,"0%1u0     ",(u16)led_mode);flash_sign = 0;}else{sprintf(COT,"0%1u0 %4u",(u16)led_mode,(u16)led_time);flash_sign = 1; }}if(seg_mode == 2){sprintf(COT,"      %02u",(u16)l_power);}SEG_TSL(COT,COD);}

补充:(忘记实现AT24C02功能)

void main()
{Close_All();Timer0_Init();//选择AIN3输出PCF8591_Write(0x03);AT24C02_Proc();while(1){SEG_Proc();Key_Proc();LED_Proc();}
}void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = (~key_now) & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){turn_sign ^= 1;}else if(key_dwon == 6){if(++set_mode == 3){set_mode = 0;seg_mode = 0;//重新计数l_count_ms = 0;p_count_ms = 0;//闪烁标志更新flash_sign = 0;l_data = 0;led_temp = 0;//保存信息到EEPROMat24_data[0] = led_mode;at24_data[1] = led_time>>8;//高八位at24_data[2] = led_time&0x00ff;//低八位AT24C02_Write(0x01,at24_data,3);}elseseg_mode = 1;}else if(key_dwon == 5){switch(set_mode){case 1:led_mode++;break;case 2:led_time+=100;break;            }//上边界属性if(led_mode >= 5)led_mode = 1;if(led_time >= 1300)led_time = 400;}    else if(key_dwon == 4){if(seg_mode == 0){seg_mode = 2;}switch(set_mode){case 1:led_mode--;break;case 2:led_time-=100;break;            }//下边界属性if(led_mode <= 0)led_mode = 4;if(led_time <= 300)led_time = 1200;}else if(key_up == 4)    {if(seg_mode == 2){seg_mode = 0;}}}
void AT24C02_Proc()
{AT24C02_Read(0x01,at24_data,3);led_mode = at24_data[0];led_time = ((at24_data[1]<<8) | at24_data[2]);
}

三、参考代码:

  1. 主函数:

#include "Public.h"
#include "Simple_Device.h"
#include "timer.h"
#include "stdio.h"
#include "SEG.h"
#include "PCF8591.h"
#include "AT24C02.h"
u8 key_delay;
u16 seg_delay;
//数码管
u8 COT[9],COD[8],PIS;
//模式
u8 seg_mode,set_mode;
//非设置模式
u16 led_time=400,l_count_ms,p_count_ms;
u8 l_data,l_power=1,led_mode=1,turn_sign=1;
u8 flash_sign    , led_temp;
//EEPROM
u8 at24_data[3];
void Key_Proc();
void SEG_Proc();
void LED_Proc();
void PCF8591_Proc();
void AT24C02_Proc();
void main()
{Close_All();Timer0_Init();//选择AIN3输出PCF8591_Write(0x03);AT24C02_Proc();while(1){SEG_Proc();Key_Proc();LED_Proc();}
}void Key_Proc()
{u8 key_now,key_dwon,key_up;static u8 key_old;if(key_delay)return;key_delay = 1;key_now = M_key();key_dwon = key_now & (key_now ^ key_old);key_up = (~key_now) & (key_now ^ key_old);key_old = key_now;if(key_dwon == 7){turn_sign ^= 1;}else if(key_dwon == 6){if(++set_mode == 3){set_mode = 0;seg_mode = 0;//重新计数l_count_ms = 0;p_count_ms = 0;//闪烁标志更新flash_sign = 0;l_data = 0;led_temp = 0;//保存信息到EEPROMat24_data[0] = led_mode;at24_data[1] = led_time>>8;//高八位at24_data[2] = led_time&0x00ff;//低八位AT24C02_Write(0x01,at24_data,3);}elseseg_mode = 1;}else if(key_dwon == 5){switch(set_mode){case 1:led_mode++;break;case 2:led_time+=100;break;            }//上边界属性if(led_mode >= 5)led_mode = 1;if(led_time >= 1300)led_time = 400;}    else if(key_dwon == 4){if(seg_mode == 0){seg_mode = 2;}switch(set_mode){case 1:led_mode--;break;case 2:led_time-=100;break;            }//下边界属性if(led_mode <= 0)led_mode = 4;if(led_time <= 300)led_time = 1200;}else if(key_up == 4)    {if(seg_mode == 2){seg_mode = 0;}}}void SEG_Proc()
{if(seg_delay)return;seg_delay = 1;//非设置模式,数码管不显示任何东西if(seg_mode == 0){sprintf(COT,"        ");    }if(seg_mode == 1){if(set_mode == 1 && flash_sign == 1){sprintf(COT,"    %4u",(u16)led_time);flash_sign = 0;}else if(set_mode == 2 && flash_sign == 1){sprintf(COT,"0%1u0     ",(u16)led_mode);flash_sign = 0;}else{sprintf(COT,"0%1u0 %4u",(u16)led_mode,(u16)led_time);flash_sign = 1; }}if(seg_mode == 2){sprintf(COT,"      %02u",(u16)l_power);}SEG_TSL(COT,COD);}void Timer0_Isr(void) interrupt 1
{l_count_ms++;p_count_ms++;if(++key_delay == 10)key_delay = 0;if(++seg_delay == 800)seg_delay = 0;SEG_Show(COD[PIS],PIS);if(++PIS == 8)PIS = 0;if(set_mode == 0){if(p_count_ms < 10*0.25*l_power)LED_Show(l_data);    elseLED_Show(0x00);if(p_count_ms == 10)p_count_ms = 0;}elseLED_Show(0x00);
}void LED_Proc()
{if(l_count_ms < led_time || !turn_sign )return;l_count_ms = 0;PCF8591_Proc();if(led_mode == 1){l_data = 0x01<>led_temp; led_temp++;if(led_temp == 8){led_temp = 0;}}else if(led_mode == 3){l_data = (0x80>>led_temp) | (0x01<>led_temp) | (0x10<
  1. 公共函数:

#ifndef PBBLIC_H
#define PBBLIC_H#include #define u8 unsigned char
#define u16 unsigned intvoid Close_All();
void Select(u8 cs,u8 s_data);    
#endif
#include "Public.h"/*向某个锁存器发送信息
*/
void Select(u8 cs,u8 s_data)
{P0 = s_data;P2 = P2 & 0x1f | (cs<<5);P2 &= 0x1f;
}/*关闭无关设备
*/
void Close_All()
{//关闭蜂鸣器和继电器Select(5,0x00);//关闭LEDSelect(4,0xff);//清空数码管数据Select(7,0xff);
}
  1. 简单外设:

#ifndef SIMPLE_DEVICE_H
#define SIMPLE_DEVICE_H#include "Public.h"void LED_Show(u8 l_data);
u8 M_key();    
#endif
#include "Simple_Device.h"/*根据输入的8位数显示LED,其中1为亮灯
*/
void LED_Show(u8 l_data)
{Select(4,~l_data);
}/*矩阵按键检测
*/
u8 M_key()
{u16 key_temp=0,i=0;//逐个置零,读取电平P44=0;P42=1;P35=1;P34=1;key_temp |= (P3&0x0f);P44=1;P42=0;P35=1;P34=1;key_temp = (key_temp<<4) | (P3&0x0f);P44=1;P42=1;P35=0;P34=1;key_temp = (key_temp<<4) | (P3&0x0f);P44=1;P42=1;P35=1;P34=0;key_temp = (key_temp<<4) | (P3&0x0f);//检测数据for(i=0;i<16;i++){if((key_temp & (0x8000>>i)) == 0)return i+4;}return 0;
}
  1. 定时器

#ifndef TIME_H
#define TIME_H#include "Public.h"void Timer0_Init(void);    
#endif
#include "timer.h"void Timer0_Init(void)        //1毫秒@12.000MHz
{AUXR |= 0x80;            //定时器时钟1T模式TMOD &= 0xF0;            //设置定时器模式TL0 = 0x20;                //设置定时初始值TH0 = 0xD1;                //设置定时初始值TF0 = 0;                //清除TF0标志TR0 = 1;                //定时器0开始计时ET0 = 1;                //使能定时器0中断EA = 1;
}
  1. 数码管:

#ifndef SEG_H
#define SEG_H#include "Public.h"void SEG_TSL(u8 *input,u8 *output);
void SEG_Show(u8 COD,u8 PIS);
#endif
#include "SEG.h"code unsigned char Seg_Table[] = 
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};/*输入字符串输出数码管代码
*/
void SEG_TSL(u8 *input,u8 *output)
{u8 i=0;for(i=0;i<8;i++){switch(input[i]){case '0':output[i] = Seg_Table[0];break;case '1':output[i] = Seg_Table[1];break;case '2':output[i] = Seg_Table[2];break;case '3':output[i] = Seg_Table[3];break;case '4':output[i] = Seg_Table[4];break;case '5':output[i] = Seg_Table[5];break;case '6':output[i] = Seg_Table[6];break;case '7':output[i] = Seg_Table[7];break;case '8':output[i] = Seg_Table[8];break;case '9':output[i] = Seg_Table[9];break;default:output[i] = 0xff;}}
}/*数码管显示函数
*/
void SEG_Show(u8 COD,u8 PIS)
{//消隐Select(7,0xff);//位选Select(6,0x01<
  1. PCF8591:

#ifndef PCF8591_H
#define PCF8591_H#include "Public.h"
#include "iic.h"void PCF8591_Write(u8 c_data);
u8 PCF8591_Read();
#endif
#include "PCF8591.h"/*写入控制字节
*/
void PCF8591_Write(u8 c_data)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(c_data);IIC_WaitAck();IIC_Stop();
}/*读取数据字节
*/
u8 PCF8591_Read()
{u8 d_data;IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();d_data = IIC_RecByte();IIC_SendAck(1);IIC_Stop();    return d_data;
}
  1. AT24C02:

#ifndef AT24C02_H
#define AT24C02_H#include "Public.h"
#include "iic.h"void AT24C02_Write(u8 w_addr,u8 *w_data,u8 num);
void AT24C02_Read(u8 r_addr,u8 *r_data,u8 num);
void AT24C02_Write1(u8 w_addr,u8 w_data);
u8 AT24C02_Read1(u8 r_addr);
void Delay5ms() ;
#endif
#include "AT24C02.h"void Delay5ms()        //@12MHz
{unsigned char i, j;i = 59;j = 90;do{while (--j);} while (--i);
}void AT24C02_Write(u8 w_addr,u8 *w_data,u8 num)
{IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(w_addr);IIC_WaitAck();while(num--){IIC_SendByte(*w_data);w_data++;IIC_WaitAck();    Delay5ms();}IIC_Stop();
}void AT24C02_Read(u8 r_addr,u8 *r_data,u8 num)
{IIC_Start();IIC_SendByte(0xa0);IIC_WaitAck();IIC_SendByte(r_addr);IIC_WaitAck();IIC_Start();IIC_SendByte(0xa1);IIC_WaitAck();while(num--){*r_data = IIC_RecByte();r_data++;if(num == 0)IIC_SendAck(1);elseIIC_SendAck(0);    }IIC_Stop();
}
  1. IIC

#ifndef _IIC_H
#define _IIC_H#include "Public.h"
#include "intrins.h"sbit SDA = P2^1;
sbit SCL = P2^0;void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
void IIC_Delay(unsigned char i);
#endif
#include "iic.h"#define DELAY_TIME 5//
void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);        
}//
void IIC_Start(void)
{SDA = 1;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 0;IIC_Delay(DELAY_TIME);SCL = 0;    
}//
void IIC_Stop(void)
{SDA = 0;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 1;IIC_Delay(DELAY_TIME);
}//
void IIC_SendAck(bit ackbit)
{SCL = 0;SDA = ackbit;                      IIC_Delay(DELAY_TIME);SCL = 1;IIC_Delay(DELAY_TIME);SCL = 0; SDA = 1;IIC_Delay(DELAY_TIME);
}//
bit IIC_WaitAck(void)
{bit ackbit;SCL  = 1;IIC_Delay(DELAY_TIME);ackbit = SDA;SCL = 0;IIC_Delay(DELAY_TIME);return ackbit;
}//
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){SCL  = 0;IIC_Delay(DELAY_TIME);if(byt & 0x80) SDA  = 1;else SDA  = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL  = 0;  
}//
unsigned char IIC_RecByte(void)
{unsigned char i, da;for(i=0; i<8; i++){   SCL = 1;IIC_Delay(DELAY_TIME);da <<= 1;if(SDA) da |= 1;SCL = 0;IIC_Delay(DELAY_TIME);}return da;    
}

四、收获:

  1. 利用STC-ISP初始化定时器时要注意开中断

  1. 初始化模块的时候最好先初始化数码管

  1. IIC写一次时间大概要5ms,不能刚进行写操作后就进行读操作,在测试模块时要着重注意

  1. 重新设置模式时记得重新计数

5、做完后记得检查有没有模块没用,有没有功能没实现

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...