钰平电子 发表于 2023-7-1 18:41:21

开源分享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]
查看完整版本: 开源分享STC8F2K16S2 STC8F2K64S4单片机最小系统32脚LQFP32封装支持替换型STC8C2K64S2