找回密码
 立即注册
查看: 526|回复: 0

分享一款STC8A8K64S4A12-28I单片机最小系统支持STC8A8K64D4单片机

[复制链接]

该用户从未签到

42

主题

7

回帖

246

积分

中级会员

积分
246
发表于 2023-6-28 01:37:20 | 显示全部楼层 |阅读模式

【简要说明】
尺寸:长107mmX宽85mmX高18mm
二、主要芯片:STC8A8K64S4A12单片机(可替换为STC8A8K64D4)CH340 、SP485
三、工作电压:直流5~36
四、支持UATR接口下载程序及USB下载(需要安卓接口线)
五、特点:
1、具有电源指示功能
2、所以I/O口以引出并有LED灯做信号指示
3、可以实现与电脑串口通信TTL通讯及RS485通讯
4、内部多晶振选择使用
5、输出IO口指示灯可以用短路帽控制
6、宽电压供电支持5~36V供电最大稳压输出电流1.5A
7、四路按键输入方便调试程序
8、采用螺旋端子压接,接线可靠方便扩展
9、调试程序方便,适合工程使用
10、供电具有防反接保护。电路工作稳定可靠


DSC_0020.JPG
DSC_0025.JPG
DSC_0019.JPG
485通讯接线说明.bmp
PCB尺寸图.bmp
标示图.bmp
端子说明.bmp
下载接线图.bmp
原图.bmp


开发板测试程序 附件资料里面有工程文件

【声明】此程序仅用于学习与参考!     
*********************************************************************/
#include <STC8.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  deng5 = P0^4;
sbit  deng6 = P0^5;
sbit  deng7 = P0^6;
sbit  deng8 = P0^7;

sbit  den2 = P4^1;
sbit  den3 = P4^2;
sbit  den4 = P4^3;
sbit  den5 = P4^4;

sbit   xd1 = P6^0;
sbit   xd2 = P6^1;
sbit   xd3 = P6^2;
sbit   xd4 = P6^3;
sbit   xd5 = P6^4;
sbit   xd6 = P6^5;
sbit   xd7 = P6^6;
sbit   xd8 = P6^7;

sbit   xxd1 = P7^0;
sbit   xxd2 = P7^1;
sbit   xxd3 = P7^2;
sbit   xxd4 = P7^3;
sbit   xxd5 = P7^4;
sbit   xxd6 = P7^5;
sbit   xxd7 = P7^6;
sbit   xxd8 = P7^7;

sbit    xxd_9 = P5^2;
sbit   xxd_10 = P5^3;
sbit   xxd_11 = P5^1;
sbit   xxd_12 = P5^0;

sbit aj1 = P5^4;
sbit aj2 = P5^5;
sbit aj3 = P4^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
        den2=~den2;//p4.1
        den3=~den3;//p4.2
          d3=~d3;//p2.2
          d5=~d5;//p2.4
          xd5=~xd5;//p6.4
          xd7=~xd7;//p6.6
          xxd4=~xxd4;//p7.3
          xxd2=~xxd2;//p7.1
          xxd_12=~xxd_12;//p5.0
         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
          d1=~d1; //p2.0
          d2=~d2; //p2.1
          d4=~d4; //p2.3
          d6=~d6; //p2.5
          xd6=~xd6;//p6.5
          xd8=~xd8;//p6.7
          xxd3=~xxd3;//p7.2
          xxd1=~xxd1;//p7.0
          xxd_11=~xxd_11;//p5.0
         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
         deng4=~deng4;//p0.3
         deng6=~deng6;//p0.5
         deng8=~deng8;//p0.7
         xxd6=~xxd6;//p7.5
         xxd8=~xxd8;//p7.7
         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;
        deng2=~deng2;
         den4=~den4;
        deng5=~deng5;
        deng7=~deng7;
          de1=~de1;
          de3=~de3;
          de5=~de5;
          de6=~de6;
          de8=~de8;
          xxd5=~xxd5;//p7.4
          xxd7=~xxd7;//p7.6
          xxd_10=~xxd_10;//p5.3
          xd1=~xd1;//p6.0
          xd3=~xd3;//p6.2
         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;
        den5=~den5;
         de7=~de7;
         xxd_9=~xxd_9; //p5.2
         xd2=~xd2;//p6.1
         xd4=~xd4;//p6.3

         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=P5=P6=P7=temp;//直接对1/0口赋值,使批输出低电平。
                for(i=0;i<9;i++)//实现广告灯的从右到左移动
                        {
                                a=temp<<i;                //左移i位
                                P3=P1=P2=P0=P4=P5=P6=P7=a;//相与求值
                                delay();                                  
                                delay();
                                delay();
                                delay();
                                delay();
                                delay();
                                delay();
                                delay();
                                delay();
                                z++;
                        }
            }
                if((z>8)&&(ga==0)){ba=1;P1=P3=P2=P0=P4=P5=P6=P7=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;
    }
}



GYJ-0281_STC8A8K64S4A12-28I单片机最小系统64脚LQFP64S封装.rar

2.93 MB, 下载次数: 23

回复 送花

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2024-5-21 00:34 , Processed in 0.057164 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表