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

相关内容

热门资讯

减租申请书 减租申请书范文(精选6篇)  随着时代在进步,用到申请书的地方很多,我们在写申请书的时候要注意态度要...
教师人事调动申请书 尊敬的领导:您们好!我们夫妻(刘军、贾容)同为合江教育事业战线上的人民教师;现将我们的工作及生活情况...
岗位调动申请书格式及 岗位调动申请书格式及范文  员工想要进行岗位的调动,可以向公司提出申请。接下来小编整理了岗位调动申请...
公司职员转正申请书 公司职员转正申请书  一、什么是申请书  申请书是个人或集体向组织、机关、企事业单位或社会团体表述愿...
先进个人申请书 先进个人申请书范文  欢迎来到公文站,本站专门为大家整理提供各种申请书,大家可以来此查找资料,下面为...
劳动仲裁申请书格式 劳动仲裁申请书格式范文  申诉人:凯,男,汉族,1986年7月19日出生,  身份证号:  住住址:...
考研期间申请自主实习范文10... 考研期间申请自主实习范文 第一篇尊敬的院领导:我是级系专业班的学生,我已经自己联系了实习就业单位,到...
项目规划申请书 项目规划申请书(精选8篇)  在当今社会高速发展的今天我们都会用到申请书,申请书是承载我们愿望和请求...
入党申请书800字 入党申请书800字(通用7篇)  在市场经济发展迅速的今天,很多场合都离不了申请书,写申请书的时候要...
劳动人事争议仲裁申请书 劳动人事争议仲裁申请书(15篇)  在人们物质精神需求不断增长的今天,我们会使用上申请书,不同的使用...
转户口申请书模版 转户口申请书模版(精选10篇)  在这个高速发展的时代,需要使用申请的场合越来越多,正确运用申请书可...
教师辞职申请书简短 教师辞职申请书简短(精选10篇)  在眼下市场经济活跃的社会,申请书使用的情况越来越多,在写作上,申...
最通用的员工转正申请书 最通用的员工转正申请书模板  经过三个月的试用期,在各方面已符合公司对员工的的要求。在转正之时,公司...
财产保全申请书范本 财产保全申请书范本  财产保全申请书的定义  财产保全申请书,是在民事案件审理过程中,公民,法人或其...
五岁儿童申请低保范文精选25... 五岁儿童申请低保范文 第一篇尊敬的领导:我叫,__县沙河站镇孟庄村第一组人.年月出生,现年岁,由于原...
职工工伤认定申请书 职工工伤认定申请书  在如今这个年代,我们每个人都可能要用到申请书,不同的使用场景有不同的申请书。写...
国家助学贷款申请书 国家助学贷款申请书(精选10篇)  国家助学贷款是由政府主导、财政贴息、财政和高校共同给予银行一定风...
工厂离职申请书 工厂离职申请书(通用16篇)  随着时代在进步,我们会使用上申请书,申请书是我们平时提出请求的一种书...
贫困户申请书 贫困户申请书模板合集十篇  当下市场经济活跃,交易频繁,申请书在生活中的使用越来越广泛,请注意不同的...
澳洲留学申请书 澳洲留学申请书6篇  当下市场经济活跃,交易频繁,有各项事务需要申请书,通过申请书,我们可以提出自己...