开源分享STC8F2K16S2 STC8F2K64S4单片机最小系统32脚LQFP32封装支持替换型STC8C2K64S2
【简要说明】尺寸:长72mm*宽76mm*高18mm主要芯片:STC8F8K16S2SP485CH340工作电压:直流6~24V支持:UART下载和USB下载(需要安卓线)【板子特点】1、所有IO口都已经引出,并有LED指示灯;2、可以一键下载;3、有五个按键输入4、可进行485通讯TTL通讯串口通讯5、输出口LED灯可使用短路帽控制6、具有防反接保护配套测试程序#include <STC8F2K08S2.h>#include <intrins.h>#define uchar unsigned char//宏定义无符号字符型#define uint unsigned int//宏定义无符号整型unsigned char T0RH = 0;//T0重载值的高字节unsigned char T0RL = 0;//T0重载值的低字节bit flagFrame = 0;//帧接收完成标志,即接收到一帧新数据bit flagTxd = 0; //单字节发送完成标志,用来替代TXD中断标志位unsigned char cntRxd = 0; //接收字节计数器unsigned char pdata bufRxd;//接收字节缓冲区void UartDriver();//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用void UartAction(unsigned char *buf, unsigned char len);//在接收到的数据帧后添加换车换行符后发回void UartWrite(unsigned char *buf, unsigned char len);//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度unsigned char UartRead(unsigned char *buf, unsigned char len);//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度void UartRxMonitor(unsigned char ms);//串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔void ConfigUART();//串口配置函数,baud-通信波特率void ConfigTimer0(unsigned int ms);//配置并启动T0,ms-T0定时时间uchar send,sendlen=0;uchar ck1=0x00;/******************************************************************** 初始定义*********************************************************************/
sbitpo5 = P3^4;sbitpo6 = P3^5;sbitpo7 = P3^6;sbitpo8 = P3^7;
sbitde1 = P1^0;sbitde2 = P1^1;sbitde3 = P1^2;sbitde4 = P1^3;sbitde5 = P1^4;sbitde6 = P1^5;sbitde7 = P1^6;sbitde8 = P1^7;
sbitd1 = P2^0;sbitd2 = P2^1;sbitd3 = P2^2;sbitd4 = P2^3;sbitd5 = P2^4;sbitd6 = P2^5;sbitd7 = P2^6;sbitd8 = P2^7;
sbitdeng1 = P0^0;sbitdeng2 = P0^1;sbitdeng3 = P0^2;sbitdeng4 = P0^3;
sbit aj1 = P5^4;sbit aj2 = P5^5;sbit aj3 = P3^0;sbit aj4 = P3^2;sbit aj5 = P3^3;
bitba=0,kt=0,kt_1=0,kt_2=0,kt_3=0,kt_4=0,fa=0,ga=0;uchar temp,z=0; //定义字符型变量uchar a,b,i;uchar trg=0,trg_1=0,trg_2=0,trg_3=0,trg_4=0,cont=0,cont_1=0,cont_2=0,cont_3=0,cont_4=0;uchar ReadData=0,ReadData_1=0,ReadData_2=0,ReadData_3=0,ReadData_4=0;
void delay()//延时程序{ uchar m,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--);}void UartAction(unsigned char *buf, unsigned char len){//接收 UartWrite(buf,len); //收到啥发回啥// if((buf==0xAA)&&(buf==0x01)&&(buf==0xBB)&&(len==3)){//串口接收例子// p01=0; //长度// send[ 0]=0xCC;// send[ 1]=0x01;// sendlen=2;// UartWrite(send, sendlen);//发送// } }
void KeyRead()//读取按键IO口函数{ ReadData = aj1^0xff;// 读取按键状态取反后赋值给ReadData trg = ReadData & (ReadData ^ cont);//trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0 cont = ReadData; //cont长按,长按cont=1,抬手后cont=0
ReadData_1 = aj2^0xff;// 读取按键状态取反后赋值给ReadData trg_1 = ReadData_1 & (ReadData_1 ^ cont_1);//trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0 cont_1 = ReadData_1; //cont长按,长按cont=1,抬手后cont=0
ReadData_2 = aj3^0xff;// 读取按键状态取反后赋值给ReadData trg_2 = ReadData_2 & (ReadData_2 ^ cont_2);//trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0 cont_2 = ReadData_2;
ReadData_3 = aj4^0xff;// 读取按键状态取反后赋值给ReadData trg_3 = ReadData_3 & (ReadData_3 ^ cont_3);//trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0 cont_3 = ReadData_3;
ReadData_4 = aj5^0xff;// 读取按键状态取反后赋值给ReadData trg_4 = ReadData_4 & (ReadData_4 ^ cont_4);//trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0 cont_4 = ReadData_4;}void key_1(){ if(trg & 0x01) //短按{ kt_3=0;kt_1=0;kt_2=0;kt_4=0; kt=1; //这是短按标志位,kt=1说明短按了 ba=1;//P1=P3=0XFF; // P1=0xff;}if((aj1!=0)&&(kt==1))//判断 { po5=~po5; //p3.4 po7=~po7; //p3.6 d1=~d1; //p2.0 d3=~d3;//p2.2 d5=~d5;//p2.4 kt=0; } // 短按
}
void key_2(){ if(trg_1 & 0x01) //短按{ kt=0;kt_3=0;kt_2=0;kt_4=0; kt_1=1; //这是短按标志位,kt=1说明短按了 ba=1;//P1=P3=0XFF;}if((aj2!=0)&&(kt_1==1))//判断 {// po2=~po2;// po4=~po4;//因为P3.3 P3.2已经为按键使用了,所以不能再控制P3.2 3.3 口了,不然按键无法使用 po6=~po6; //p3.5 po8=~po8; //p3.7 d2=~d2; //p2.1 d4=~d4; //p2.3 d6=~d6; //p2.5 kt_1=0; } // 短按}
void key_3(){ if(trg_2 & 0x01) //短按{ kt=0;kt_1=0;kt_3=0;kt_4=0; kt_2=1; //这是短按标志位,kt=1说明短按了 ba=1;//P1=P3=0XFF;}if((aj3!=0)&&(kt_2==1))//判断 { d7=~d7; //p2.6 deng1=~deng1;//p0.0 deng3=~deng3;//p0.2
kt_2=0; } // 短按}
void key_4(){ if(trg_3 & 0x01) //短按{ kt=0;kt_1=0;kt_2=0;kt_4=0; kt_3=1; //这是短按标志位,kt=1说明短按了 ba=1;//P1=P3=0XFF;}if((aj4!=0)&&(kt_3==1))//判断 { d8=~d8; //P2.7 deng2=~deng2; //P0.1 deng4=~deng4;//p0.3 de1=~de1; de3=~de3; de5=~de5; de7=~de7; kt_3=0; } // 短按}
void key_5(){ if(trg_4 & 0x01) //短按{ kt=0;kt_1=0;kt_2=0;kt_3=0; kt_4=1; //这是短按标志位,kt=1说明短按了 ba=1;//P1=P3=0XFF;}if((aj5!=0)&&(kt_4==1))//判断 { de2=~de2; de4=~de4; de6=~de6; de8=~de8; kt_4=0; } // 短按}void main(){ EA = 1; //开总中断 ConfigTimer0(1); //配置T0定时1ms ConfigUART();//配置波特率为9600 temp=0xfE; //11111110定义每次一个灯亮 while(1){ UartDriver();//调用串口驱动 if(ba==0) { P3=P1=P2=P0=P4=temp;//直接对1/0口赋值,使批输出低电平。 for(i=0;i<9;i++)//实现广告灯的从右到左移动 { a=temp<<i; //左移i位 P3=P1=P2=P0=P4=a;//相与求值 delay(); delay(); delay(); delay(); delay(); delay(); delay(); delay(); delay(); delay(); delay(); z++; } } if((z>8)&&(ga==0)){ba=1;P1=P3=P2=P0=P4=0XFF;ga=1;z=0;} //流水一遍结束// KeyRead(); key_1(); key_2(); key_3(); key_4(); key_5(); }}void InterruptTimer0() interrupt 1{//T0中断服务函数,执行串口接收监控 TH0 = T0RH;//重新加载重载值 TL0 = T0RL; UartRxMonitor(1);//串口接收监 KeyRead();}void InterruptUART() interrupt 4{//串口中断服务函数 if (RI) { //接收到新字节 RI = 0;//清零接收中断标志位 if (cntRxd < sizeof(bufRxd)) {//接收缓冲区尚未用完时,保存接收字节,并递增计数器 bufRxd = SBUF; // cntRxd++这个很重要,一开始 cntRxd < sizeof(bufRxd)当进入函数的次数增加,cntRxd慢慢变大,当传入的数据不满的时候就 用时间检测,判断是否是传输完成 } } if (TI) { //字节发送完毕 TI = 0; //清零发送中断标志位 flagTxd = 1;//设置字节发送完成标志 }}void ConfigTimer0(unsigned int ms){//配置并启动T0,ms-T0定时时间 unsigned long tmp;//临时变量 tmp = 11059200 / 12; //定时器计数频率 tmp = (tmp * ms) / 1000;//计算所需的计数值 tmp = 65536 - tmp; //计算定时器重载值 tmp = tmp + 33; //补偿中断响应延时造成的误差 T0RH = (unsigned char)(tmp>>8);//定时器重载值拆分为高低字节 T0RL = (unsigned char)tmp; TMOD &= 0xF0; //清零T0的控制位 TMOD |= 0x01; //配置T0为模式1 TH0 = T0RH; //加载T0重载值 TL0 = T0RL; ET0 = 1; //使能T0中断 TR0 = 1; //启动T0}void ConfigUART(){//串口配置函数,baud-通信波特率 SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0xE0; //设定定时初值 T2H = 0xFE; //设定定时初值 AUXR |= 0x10; //启动定时器2 ES= 1; //使能串口中断}void UartWrite(unsigned char *buf, unsigned char len){//串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 while (len--){ //循环发送所有字节 flagTxd = 0; //清零发送标志 SBUF = *buf++; //发送一个字节数据 while (!flagTxd); //等待该字节发送完成 }}unsigned char UartRead(unsigned char *buf, unsigned char len){//串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 unsigned char i; if (len > cntRxd){//指定读取长度大于实际接收到的数据长度时,读取长度设置为实际接收到的数据长度 len = cntRxd; } for (i=0; i<len; i++){//拷贝接收到的数据到接收指针上 *buf++ = bufRxd; } cntRxd = 0;//接收计数器清零 return len;//返回实际读取长度}void UartDriver(){//串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用 unsigned char len; unsigned char pdata buf; if (flagFrame){ //有命令到达时,读取处理该命令 flagFrame = 0; len = UartRead(buf, sizeof(buf)-2); //将接收到的命令读取到缓冲区中 UartAction(buf, len);//传递数据帧,调用动作执行函数 }}void UartRxMonitor(unsigned char ms){//串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 static unsigned char cntbkp = 0; static unsigned char idletmr = 0; if (cntRxd > 0){//接收计数器大于零时,监控总线空闲时间 if (cntbkp != cntRxd){//接收计数器改变,即刚接收到数据时,清零空闲计时 cntbkp = cntRxd; idletmr = 0; }else{ //接收计数器未改变,即总线空闲时,累积空闲时间 if (idletmr < 30){//空闲计时小于30ms时,持续累加 idletmr += ms; if (idletmr >= 30){//空闲时间达到30ms时,即判定为一帧接收完毕 flagFrame = 1;//设置帧接收完成标志 } } } }else{ cntbkp = 0; }}
页:
[1]