找回密码
 立即注册
楼主: ZIJIN_CHJ

STC32G12k128实验箱学习记录

[复制链接]
已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 2026-10-15 13:47:03 | 显示全部楼层

视频教学及教课书:《32位8051单片机原理及应用》,何宾教授主讲
https://www.stcaimcu.com/thread-3355-1-1.html
(出处: 国芯人工智能技术交流网站)
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 2026-10-19 18:51:19 | 显示全部楼层
屏幕截图 2026-10-19 141637.png

回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 2026-10-19 18:55:34 | 显示全部楼层


屏幕截图 2026-10-19 184911.png
屏幕截图 2026-10-19 184936.png
屏幕截图 2026-10-19 185026.png
屏幕截图 2026-10-19 144004.png

回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 2026-10-21 12:27:48 | 显示全部楼层
我的STC 32G 12K128 实验箱,下载代码包里的串口发送程序,初始发送的字符串不会发送,点击可以发送是什么问题?
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 2026-10-29 08:51:13 | 显示全部楼层
实验箱流水灯程序,按键控制流水灯模式。

#include <STC32G.H>
#include "KEY_Drive.H"

/*----------按键变量声明----------*/
unsigned char Key_Slow_Down;                                                //按键消抖变量
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;                //按键检测变量

unsigned char Uled = 0xFE;
unsigned char Led_Mode;
bit Led_Flag;
unsigned char Led_Date[]= {0x7E,0xBD,0xDB,0xE7};
unsigned char Led_Index;
unsigned int Time = 500;
void Delay(unsigned int xms)        //@22.1184MHz
{
        unsigned long edata i;

        while(--xms)
        {
                _nop_();
                i = 5528UL;
                while (i) i--;

        }
       
}
//========================================================================
// 函数: 按键处理函数
// 描述: 通过按键控制LED流水灯
// 参数: 无
// 返回: 无
// 备注:
//========================================================================

void Key_Proc()
{
        if(Key_Slow_Down)return;                        //按键消抖
        Key_Slow_Down = 1;
       
        Key_Val=Key_Read();                                        //读取键码值
        Key_Down=Key_Val&(Key_Val^Key_Old);        //检测下降沿
        Key_Up=~Key_Val&(Key_Val^Key_Old);        //检测上升沿
        Key_Old=Key_Val;                                        //扫描辅助变量
       
        switch(Key_Down)
        {
                case 1:
                        Led_Flag=1;
               
                        break;
                case 2:
                        Led_Flag=0;
       
                        break;
                case 3:
                        Led_Mode++;
                        if(Led_Mode>=4)
                        {
                                Led_Mode=0;
                        }
                        break;
                case 4:
                        Led_Mode--;
                        if(Led_Mode<=255)
                        {
                                Led_Mode=3;
                        }
                        break;
                case 5:
                        Time+=100;
                        if(Time >=1000)
                                Time=1000;
                        break;
                case 6:
                        Time-=100;
                        if(Time <=100)
                                Time=100;
                        break;
                default:break;
        }
}
void Led_Proc()
{
        if(Led_Flag==1)
        {
                switch(Led_Mode)
                {
                        case 0:
                                Uled= _cror_ (Uled,1);
                                P6 = Uled;
                                Delay(Time);
                               
                                break;
                        case 1:
                                Uled= _crol_ (Uled,1);
                                P6 = Uled;
                                Delay(Time);
                               
                                break;
                        case 2:
                                Led_Index++;
                                if(Led_Index>=4)Led_Index=0;
                                P6 = Led_Date[Led_Index];
                                Delay(300);
                               
                                break;
                        case 3:
                                Led_Index--;
                                if(Led_Index==255)Led_Index=3;
                                P6 = Led_Date[Led_Index];
                                Delay(200);
                               
                                break;
                        default:break;
                       
                }
               
        }
       
}



void Timer0_Init(void)                //1毫秒@22.1184MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x9A;                                //设置定时初始值
        TH0 = 0xA9;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

void main()
{
//        unsigned volatile long i;
       
        WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
        EAXSFR();//扩展 SFR(XFR)访问使能
        CKCON =0; //提高访问XRAM速度
       
        P0M0 = 0x00; P0M1 = 0x00;
        P1M0 = 0x00; P1M1 = 0x00;
        P4M0 = 0x00; P4M1 = 0x00;
        P6M0 = 0x00; P6M1 = 0x00;
       
        Timer0_Init();
        EA = 1;
       
        P40 = 0;
        while(1)
        {
                Key_Proc();
                Led_Proc();
               
        }
}

void Timer0_Isr(void) interrupt 1
{
        if(++Key_Slow_Down==20)
                Key_Slow_Down = 0;
       
       
}
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 6 天前 | 显示全部楼层
stc32g12k128实验箱串口发送函数,利用串口实现不停电下载函数:

#include "MAIN_ALL.H"

#define BRT   (65536 - MAIN_Fosc / 115200 / 4)        //定时器2重载值(1T模式)

bit busy;                        //忙标志
char wptr;                        //接收缓冲区指针
char rptr;                        //发送缓冲区指针
char buffer[16];        //
bit Rxt_Flag = 0;        //接收标志
bit Uart1_Flag = 1;        //发送标志
u8 code Uart1_Up_Buffer[]={"\n\r温度:  按键:  "};
u8 xdata Uart1_Up_Num[10];
/*-------串口1初始化函数-------*/
void Uart1Init()
{
        SCON |= 0x50;        //SCON 串口1控制寄存器,模式1,可变波特率8位数据方式
        T2L = BRT;                //定时定时器2低字节装载重装值 低8位
        T2H = BRT>>8;   //定时定时器2高字节装载重装值 高8位
        S1BRT = 1;      //串口1波特率发生器选择位:0=定时器1,1=定时器2作为波特率发生器
        T2x12 = 1;      //定时器2的1T/12T选择位:1 = 1T模式。(不分频)
        T2R = 1;        //启动定时器2运行
        ES = 1;
        wptr = 0x00;    //接收缓冲区读指针清零
        rptr = 0x00;    //发送缓冲区写指针清零
        busy = 0;       //发送忙标志清零(表示当前无发送任务)


}
/*-------串口1数据发送函数-------*/
void Uart1_Up_Data()
{
        static u8 xdata count=0;
        if(Uart1_Flag)
        {
                Uart1_Flag=0;
               
                count++;
                switch(count)
                {
                        case 1:SBUF=Uart1_Up_Buffer[0];break;
                        case 2:SBUF=Uart1_Up_Buffer[1];break;
                        case 3:SBUF=Uart1_Up_Buffer[2];break;
                        case 4:SBUF=Uart1_Up_Buffer[3];break;
                        case 5:SBUF=Uart1_Up_Buffer[4];break;
                        case 6:SBUF=Uart1_Up_Buffer[5];break;
                        case 7:SBUF=Uart1_Up_Buffer[6];break;
                        case 8:SBUF=Uart1_Up_Buffer[7];break;
                        case 9:SBUF=Uart1_Up_Num[0];break;
                        case 10:SBUF=Uart1_Up_Num[1];break;
                        case 11:SBUF=Uart1_Up_Num[2];break;
                        case 12:SBUF=Uart1_Up_Num[3];break;
                       
                        case 13:SBUF=Uart1_Up_Buffer[8];break;
                        case 14:SBUF=Uart1_Up_Buffer[9];break;
                        case 15:SBUF=Uart1_Up_Buffer[10];break;
                        case 16:SBUF=Uart1_Up_Buffer[11];break;
                        case 17:SBUF=Uart1_Up_Buffer[12];break;
                        case 18:SBUF=Uart1_Up_Buffer[13];break;
                        case 19:SBUF=Uart1_Up_Buffer[14];break;
                        case 20:SBUF=Uart1_Up_Num[5];break;
                        case 21:SBUF=Uart1_Up_Num[6];break;
                        case 22:SBUF=Uart1_Up_Num[7];break;
                        case 23:count = 0;break;
                        default:break;
                               
                }
        }
}
//------------单字节发送--------------
void Uart1Send(char dat)
{
//        while(busy);        //等待“忙”标志释放(等待上一次发送完成)
        busy  = 1;      //置忙,表示正在发送
        SBUF = dat;     //写入发送数据寄存器,启动发送
       
}
//------------字符串发送--------------
void Uart1SendStr(char *p)
{
        while(*p)
        {
                Uart1Send(*p++);        //逐字节发送,直到遇到 '\0'
        }
}
/*-------串口1中断服务函数-------*/
void Uart1Isr() interrupt 4
{
        static char Uart1_ser_n = 0;
        if(TI)                                                // 发送完成标志
        {               
                TI = 0;                                        //必须软件清零
                busy = 0;                //一个字节发送完释放忙标志
                Uart1_Flag = 1;
                Uart1_Up_Data();
        }               
        if(RI)                                                //接收完成标志
        {               
                RI = 0;                                        //必须软件清零
                Uart1_Flag = 1;
                wptr = SBUF;
                if(SBUF==0x00)                //如果连续10次接收到0x00,复位到程序下载区实现不停电下载
                {
                        Uart1_ser_n++;
                        if(Uart1_ser_n>=10)
                        {
                                Uart1_ser_n=0;
                                IAP_CONTR|=0x60;
                        }
                }
//                buffer[wptr++] = SBUF;        //收到的字节存入缓冲区,写指针后移
//                wptr &= 0x0f;
        }
}
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 6 天前 | 显示全部楼层
ZIJIN*** 发表于 2026-11-1 21:05
stc32g12k128实验箱串口发送函数,利用串口实现不停电下载函数:

#include "MAIN_ALL.H"

屏幕截图 2026-11-01 210632.png


串口显示的温度值 和按键值,并能实现不停电下载。
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 前天 21:20 | 显示全部楼层
stc32g12k128内部RTC时钟程序,用数码管显示,按键设置显示界面和调整时间。
//========================================================================
// 函数: 数码管显示函数
// 描述: 数码管显示9个显示界面,在时钟显示界面显示,年,月,日, 时,分,秒和闹钟时间
//                在设置界面显示,设置界面的年,月,日, 时,分,秒和闹钟时间,在其它显示界面分别显示
//                红外遥控的键值,当前的温度和其它的显示内容
// 参数: 无
// 返回: 无
// 备注:
//========================================================================

void Seg_Display()
{       
        if(Seg_Disp_Mode==0)
        {
                switch(Timer_Display_Mode)                        //时钟显示界面
                {
                        case 0:
                                LED8[0] = DispDay[0]/10;        //年
                                LED8[1] = DispDay[0]%10;
                                LED8[2] = 0x11;
                                LED8[3] = DispDay[1]/10;        //月
                                LED8[4] = DispDay[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = DispDay[2]/10;        //日
                                LED8[7] = DispDay[2]%10;
                                break;
                        case 1:
                                if(DispTime[0]>=10)LED8[0] = DispTime[0]/10;
                                else                 LED8[0] = 0x10;
                               
                                LED8[1] = DispTime[0]%10;        //时
                                LED8[2] = 0x11;
                                LED8[3] = DispTime[1]/10;        //分
                                LED8[4] = DispTime[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = DispTime[2]/10;        //秒
                                LED8[7] = DispTime[2]%10;
                                break;
                        case 2:
                                LED8[0] = Disp_Alarm[0]/10;        //闹钟时
                                LED8[1] = Disp_Alarm[0]%10;
                                LED8[2] = 0x11;
                                LED8[3] = Disp_Alarm[1]/10;        //闹钟分
                                LED8[4] = Disp_Alarm[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = Disp_Alarm[2]/10;        //闹钟秒
                                LED8[7] = Disp_Alarm[2]%10;
                                break;
                        default:break;
                }
               
        }
        else if(Seg_Disp_Mode==1)                                //时钟设置界面
        {
                switch(Timer_Set_State)
                {
                        case 0:
                                LED8[0] = Date_Set[0]/10;        //日期
                                LED8[1] = Date_Set[0]%10;
                                LED8[2] = 0x11;
                                LED8[3] = Date_Set[1]/10;
                                LED8[4] = Date_Set[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = Date_Set[2]/10;
                                LED8[7] = Date_Set[2]%10;
                                switch(Timer_Index)                        //在设置界面选择设置的位以500ms的时间间隔闪烁
                                {
                                        case 0:
                                                LED8[0] = Blink_Flag? Date_Set[0]/10%10:0x10;
                                                LED8[1] = Blink_Flag? Date_Set[0]%10:0x10;
                                        break;
                                        case 1:
                                                LED8[3] = Blink_Flag? Date_Set[1]/10:0x10;
                                                LED8[4] = Blink_Flag? Date_Set[1]%10:0x10;
                                        break;
                                        case 2:
                                                LED8[6] = Blink_Flag? Date_Set[2]/10:0x10;
                                                LED8[7] = Blink_Flag? Date_Set[2]%10:0x10;
                                        break;
                                }
                                break;
                        case 1:
                               
                                LED8[0] = Clock_Set[0]/10;        //时间
                                LED8[1] = Clock_Set[0]%10;
                                LED8[2] = 0x11;
                                LED8[3] = Clock_Set[1]/10;
                                LED8[4] = Clock_Set[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = Clock_Set[2]/10;
                                LED8[7] = Clock_Set[2]%10;
                       
                                LED8[0+Timer_Index*3] = Blink_Flag? Clock_Set[Timer_Index]/10%10:0x10;
                                LED8[1+Timer_Index*3] = Blink_Flag? Clock_Set[Timer_Index]%10:0x10;
                                break;
                        case 2:
                                LED8[0] = Set_Alarm[0]/10;        //闹钟
                                LED8[1] = Set_Alarm[0]%10;
                                LED8[2] = 0x11;
                                LED8[3] = Set_Alarm[1]/10;
                                LED8[4] = Set_Alarm[1]%10;
                                LED8[5] = 0x11;
                                LED8[6] = Set_Alarm[2]/10;
                                LED8[7] = Set_Alarm[2]%10;
                       
                                LED8[0+Timer_Index*3] = Blink_Flag? Set_Alarm[Timer_Index]/10%10:0x10;
                                LED8[1+Timer_Index*3] = Blink_Flag? Set_Alarm[Timer_Index]%10:0x10;
                                break;
                        default:break;
                       
                       
                }
        }
        else if(Seg_Disp_Mode==2)                                        //其它显示界面
        {
                switch(Ucled_Diap_Mode)
                {
                        case 0:
                               
                                LED8[0] = Ir_Code[4]/16;        //红外遥控的长按
                                LED8[1] = Ir_Code[4]%16;
                                LED8[2] = 0x10;
                                LED8[3] = Ir_Code[0]/16;        //红外遥控的地址
                                LED8[4] = Ir_Code[0]%16;
                                LED8[5] = 0x10;
                                LED8[6] = Ir_Code[2]/16;        //红外遥控的键码
                                LED8[7] = Ir_Code[2]%16;
                                       
                                break;
                        case 1:
                                LED8[0] = 0x10;
                                LED8[1] = 0x10;
                                LED8[2] = 0x10;
                                LED8[3] = 0x10;
                                LED8[4] = 0x10;
                                LED8[5] = Temp/100%10;                        //DS18B20读取的温度
                                LED8[6] = (Temp/10%10)|0x20;
                                LED8[7] = Temp%10;
                                break;
                        case 2:
                               
                                LED8[0] = 0x11;                                        //其它
                                LED8[1] = 0x11;
                                LED8[2] = 0x11;
                                LED8[3] = 0x11;
                                LED8[4] = 0x11;
                                LED8[5] = 0x11;
                                LED8[6] = DispTime[2]/10;
                                LED8[7] = DispTime[2]%10;
                                break;
                        default:break;
                }
               
        }
         
}
回复

使用道具 举报 送花

已绑定手机

9

主题

231

回帖

366

积分

中级会员

积分
366
 楼主| 发表于 前天 21:28 | 显示全部楼层
按键处理函数:
//========================================================================
// 函数: 按键处理函数
// 描述: 用按键1切换显示的模式,按键2控制各个模式下的显示界面,按键6,7在设置状态下设置时间日期等
//                按键4,切换设置的位,按键8保存退出设置状态
// 参数:
// 返回:
// 备注:
//========================================================================

void Key_Proc()
{
        if(Key_Slow_Down)return;
        Key_Slow_Down = 1;
       
        Key_Val=Key_Read();                                        //读取键码值
        Key_Dow=Key_Val&(Key_Val^Key_Old);        //检测下降沿
        Key_Up=~Key_Val&(Key_Val^Key_Old);        //检测上升沿
        Key_Old=Key_Val;                                        //扫描辅助变量
       
        switch(Key_Dow)
        {
                case 1:                     //按键1,切换显示模式,0- 日期,1- 时间,2- 闹钟
                       
                                Seg_Disp_Mode++;               
                                Seg_Disp_Mode %= 3;
                       
                        break;
                case 2:                                                //按键2,在时钟显示界面切换显示日期,时间 和闹钟
                        if(Seg_Disp_Mode==0)
                        {
                                if(++Timer_Display_Mode==3)
                                        Timer_Display_Mode=0;
                        }
                        else if(Seg_Disp_Mode==1)        //在时钟设置界面切换显示日期,时间 和闹钟的设置界面
                        {
                                Timer_Set_State++;
                                Timer_Set_State %= 3;
                                Timer_Index = 0;
                        }
                        else if(Seg_Disp_Mode==2)        //其它显示界面
                        {
                                if(++Ucled_Diap_Mode==3)
                                        Ucled_Diap_Mode=0;
                        }
                        break;
                case 3:                                                       
                       
                        break;
                case 5:
                       
                        break;
                case 6:        // 数值 +1
                if(Seg_Disp_Mode==1)
                {
                        if(Timer_Set_State == 0)        // 设置日期 Date_Set[0]年,[1]月,[2]日
                        {
                                Date_Set[Timer_Index]++;
                                if(Timer_Index == 0 && Date_Set[0] >= 100)        //年份0~99
                                        Date_Set[0] = 0;
                                if(Timer_Index == 1 && Date_Set[1] >= 13)        //月份1~12
                                        Date_Set[1] = 1;
                                if(Timer_Index == 2 && Date_Set[2] >= 32)        //日期1~31
                                        Date_Set[2] = 1;
                        }
                        else if(Timer_Set_State == 1)        // 设置时钟 Clock_Set[0]时 [1]分 [2]秒
                        {
                                Clock_Set[Timer_Index]++;
                                if(Timer_Index == 0 && Clock_Set[0] >= 24)
                                        Clock_Set[0] = 0;
                                if(Timer_Index == 1 && Clock_Set[1] >= 60)
                                        Clock_Set[1] = 0;
                                if(Timer_Index == 2 && Clock_Set[2] >= 60)
                                        Clock_Set[2] = 0;
                        }
                        else if(Timer_Set_State == 2)        // 设置闹钟 Set_Alarm[0]时 [1]分 [2]秒
                        {
                                Set_Alarm[Timer_Index]++;
                                if(Timer_Index == 0 && Set_Alarm[0] >= 24)
                                        Set_Alarm[0] = 0;
                                if(Timer_Index == 1 && Set_Alarm[1] >= 60)
                                        Set_Alarm[1] = 0;
                                if(Timer_Index == 2 && Set_Alarm[2] >= 60)
                                        Set_Alarm[2] = 0;
                        }
                }
                break;
        case 7:        // 数值 -1
                if(Seg_Disp_Mode==1)
                {
                        if(Timer_Set_State == 0)        //日期
                        {
                                Date_Set[Timer_Index]--;
                                if(Timer_Index == 0 && Date_Set[0] > 99)        //溢出变成255,回99
                                        Date_Set[0] = 99;
                                if(Timer_Index == 1 && Date_Set[1] < 1)
                                        Date_Set[1] = 12;
                                if(Timer_Index == 2 && Date_Set[2] < 1)
                                        Date_Set[2] = 31;
                        }
                        else if(Timer_Set_State == 1)        //时钟
                        {
                                Clock_Set[Timer_Index]--;
                                if(Timer_Index == 0 && Clock_Set[0] > 23)
                                        Clock_Set[0] = 23;
                                if(Timer_Index == 1 && Clock_Set[1] > 59)
                                        Clock_Set[1] = 59;
                                if(Timer_Index == 2 && Clock_Set[2] > 59)
                                        Clock_Set[2] = 59;
                        }
                        else if(Timer_Set_State == 2)        //闹钟
                        {
                                Set_Alarm[Timer_Index]--;
                                if(Timer_Index == 0 && Set_Alarm[0] > 23)
                                        Set_Alarm[0] = 23;
                                if(Timer_Index == 1 && Set_Alarm[1] > 59)
                                        Set_Alarm[1] = 59;
                                if(Timer_Index == 2 && Set_Alarm[2] > 59)
                                        Set_Alarm[2] = 59;
                        }
                }
                break;
                case 4:
                        if(Seg_Disp_Mode==1)        //在设置模式下修改设置的位
                        {
                                Timer_Index++;
                                Timer_Index %= 3;
                        }
                       
                        break;
                case 8:
                        if(Seg_Disp_Mode==1)        //如果在设置状态下,保存设置时间并退出设置
                        {
                                Rtc_Config();
                       
                                Seg_Disp_Mode = 0;
                                Timer_Index = 0;
                        }
                        break;
                default:break;
        }
}
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-11-7 14:50 , Processed in 0.073438 second(s), 73 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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