【简要说明】 尺寸:长72mm*宽76mm*高18mm 主要芯片:STC8F8K16S2 SP485 CH340 工作电压:直流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[100]; //接收字节缓冲区 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[50],sendlen=0; uchar ck1=0x00; /******************************************************************** 初始定义 *********************************************************************/
sbit po5 = P3^4; sbit po6 = P3^5; sbit po7 = P3^6; sbit po8 = P3^7;
sbit de1 = P1^0; sbit de2 = P1^1; sbit de3 = P1^2; sbit de4 = P1^3; sbit de5 = P1^4; sbit de6 = P1^5; sbit de7 = P1^6; sbit de8 = P1^7;
sbit d1 = P2^0; sbit d2 = P2^1; sbit d3 = P2^2; sbit d4 = P2^3; sbit d5 = P2^4; sbit d6 = P2^5; sbit d7 = P2^6; sbit d8 = P2^7;
sbit deng1 = P0^0; sbit deng2 = P0^1; sbit deng3 = P0^2; sbit deng4 = P0^3;
sbit aj1 = P5^4; sbit aj2 = P5^5; sbit aj3 = P3^0; sbit aj4 = P3^2; sbit aj5 = P3^3;
bit ba=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[0]==0xAA)&&(buf[1]==0x01)&&(buf[2]==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[cntRxd++] = 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[40]; 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; } }
|