蓝桥杯单片机第九届省赛编程题(深夜学习——单片机)
创始人
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、做完后记得检查有没有模块没用,有没有功能没实现

相关内容

热门资讯

校园的春天四年级作文400字... 校园的春天四年级作文400字 篇一春天是一个充满生机和希望的季节,而校园的春天更是美丽而多彩的。每年...
我和神笔马良过一天四年级作文... 我和神笔马良过一天四年级作文 篇一在一个晴朗的周末早晨,我和神笔马良一起度过了一个奇幻的一天。早上醒...
远离危险,珍爱生命作文【通用... 远离危险,珍爱生命作文 篇一近年来,随着社会的发展和人们生活水平的提高,人们对生命的重视程度越来越高...
游崇武古城四年级作文450字... 游崇武古城四年级作文450字 篇一游崇武古城我最近去了一座古城,叫做崇武古城。这座古城位于福建省漳州...
夏天作文400字四年级(实用... 夏天作文400字四年级 篇一夏天的一天夏天是我最喜欢的季节之一。夏天的早晨总是阳光明媚,鸟儿欢快地唱...
四年级写做叶画的作文(最新3... 四年级写做叶画的作文 篇一我喜欢画画,而且我最喜欢画的是叶子。叶子有各种各样的形状和颜色,所以每一片...
四年级作文三亚蜈支洲15篇【... 四年级作文三亚蜈支洲15篇 篇一:蜈支洲的美景蜈支洲是我国的一个美丽的海岛,位于海南省三亚市附近。我...
小学四年级周记【优选6篇】 小学四年级周记 篇一今天天气晴朗,我和同学们一起来到学校。早上的第一节课是数学课,老师教我们学习了一...
我的朋友四年级学生作文【优选... 我的朋友四年级学生作文 篇一我的朋友小明我有一个好朋友,他叫小明。小明是一个四年级的学生,他是个聪明...
开学第一天作文四年级300字... 篇一:开学第一天作文四年级300字16篇第一篇内容:开学第一天的新鲜感今天是开学的第一天,我早早地起...
我的妈妈四年级作文(实用6篇... 我的妈妈四年级作文 篇一:我的妈妈是最好的妈妈我的妈妈是一位非常了不起的妈妈。她是我的榜样和朋友。她...
金仓湖四年级作文(最新6篇) 金仓湖四年级作文 篇一秋天的金仓湖金仓湖是我家附近的一个美丽湖泊,它四季如春,我最喜欢的季节是秋天。...
我喜欢春天四年级优秀作文【最... 我喜欢春天四年级优秀作文 篇一春天是一年中最美丽的季节,我非常喜欢春天。春天来了,大地变得生机勃勃,...
四年级300字350字作文(... 四年级300字作文 篇一: 我最喜欢的动物我最喜欢的动物是熊猫。熊猫是中国的国宝,它们有着黑白相间的...
我自己作文600字(精选4篇... 我自己作文600字 篇一我的追梦之路人生如同一场漫长的旅行,每个人都带着自己的梦想踏上这个旅程。而我...
我心中的秘密作文四年级300... 我心中的秘密作文四年级300字63篇 篇一标题:小猫咪的秘密我家养了一只小猫咪,它是我心中的秘密。它...
捉螃蟹六年级作文(经典3篇) 捉螃蟹六年级作文 篇一:难忘的螃蟹之旅今年夏天,我和家人一起去了一个美丽的海边小镇度假。除了游泳、沙...
好样的,家乡菜四年级作文(实... 好样的,家乡菜四年级作文 篇一家乡菜是我最喜欢的美食之一。它不仅味道鲜美,而且富含各种营养成分。我想...
四年级期末作文【经典5篇】 四年级期末作文 篇一:我的暑假计划暑假就要到了,我已经迫不及待地想要开始我的暑假计划了。这个暑假,我...
温暖的时刻作文600字六年级... 温暖的时刻作文600字六年级 篇一温暖的时刻今天是一个特别温暖的日子,阳光明媚,微风轻拂,仿佛整个世...