scpcw
发表于 2025-2-20 09:11:56
tianjing818 发表于 2025-2-20 08:26
必须点赞
一定把AI8051这个小可爱搞好
scpcw
发表于 2025-2-20 09:13:02
tianjing818 发表于 2025-2-20 08:26
必须点赞
认真学习这个小可爱,把她搞透彻。
zhaoye818
发表于 2025-2-20 09:34:42
scpcw 发表于 2025-2-20 09:10
有了大神的肯定,必须加油
我不是大神,一起学习一起加油。
scpcw
发表于 2025-2-20 21:57:49
我总结的ISP虚拟 数码管 LED函数使用
//SEG7_ShowString("a%d b%d", (char)single_double+1,GongDe); //用printf的格式化参数
//SEG7_ShowLong(GongDe,16); //用16进制显示
//SEG7_ShowFloat(3.14159); //显示小数
//------------------------------------------
// byte cod
// cod = 0x3f|0x80; //或0x80加小数点
// cod = 0x06;
// cod = 0x5b;
// cod = 0x0; //0x00空格
// cod = 0x66;
// cod = 0x6d;
// cod = 0x71;
// cod = 0x71;
// SEG7_ShowCode(cod); //用段码显示
//--------------------------------------
// LCD12864_DisplayClear(); //清屏
// LCD12864_AutoWrapOn(); //自动换行
/*/----------------------------------------------------
cod = 0x4c; //LCD所有命令前4字节都是LCD+0x80
cod = 0x43; //LCD所有命令前4字节都是LCD+0x80
cod = 0x44; //LCD所有命令前4字节都是LCD+0x80
cod = 0x80; //LCD所有命令前4字节都是LCD+0x80
cod = 0x01; //LCD所有命令第5字节都是后面字节数
cod = 0xa6; //0xa6:清屏 (0xa7):显示ASCII字符( 0xa7 0x0 0x0)X,Y坐标
USB_SendData(cod,0x06);//测试直接用命令字体清屏LCD12864_DisplayClear();
*/
/*/----------------------------------------------------------------
任务1,发送123到缓存
功能17: 上传数据到缓冲区
命令格式: 4CH 43H 44H 80H x1 AFH ah al xx ...
功能15:显示字符在LCD12864上显示ASCII码和简体中文字符
命令格式: 4CH 43H 44H 80H 03H A7H x y
-----------------------------------------------------------------------*/
//----------用命令发送------------------------------------
// LCD12864_DisplayClear(); //清屏
// LCD12864_AutoWrapOn(); //自动换行
// cod= 0x4c; //LCD所有命令前4字节都是LCD+0x80
// cod= 0x43; //LCD所有命令前4字节都是LCD+0x80
// cod= 0x44; //LCD所有命令前4字节都是LCD+0x80
// cod= 0x80; //LCD所有命令前4字节都是LCD+0x80
// cod= 7; //LCD所有命令第11字节都是后面字节数7
// cod= 0xaf; //0xaf:发送数据到缓存
// cod= 0x00; //发送地址高位
// cod= 0x00; //发送地址低位
// cod= 0x31; //发送'1'
// cod= 0x32; //发送'2'
// cod = 0x33; //发送'3'
// cod = 0x00; //发送00结束符
// USB_SendData(cod,12);//测试直接用命令字体清屏LCD12864_DisplayClear();
//
// cod= 0x03; //LCD所有命令第5字节都是后面字节数8
// cod= 0xa7; //0xaf:发送数据到缓存
// cod= 0x0; //第2列
// cod= 0x0; //第0行
// USB_SendData(cod,0x8);//显示字符
//----------用数组发字符串
cod= '1'; //LCD所有命令前4字节都是LCD+0x80
cod= 'a'; //LCD所有命令前4字节都是LCD+0x80
cod= GongDe+0x30; //LCD所有命令前4字节都是LCD+0x80
cod= 00;
LCD12864_ShowString(0, 0, cod);
scpcw
发表于 2025-2-21 16:45:52
第八集 定时器周期性调度任务
官方给了一个利用定时器周期性调度度任务的模板
我把模板裁减最小化,分析了一下:
#include "config.h"
#include "io.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
//----------以上为USB参数赋值----
typedef struct
{
u8 Run; //任务是否运行:Run/Stop
u16 TIMCount; //运行的时间片
u16 TRITime; //重载值,前面减完从这里又复制去
void (*TaskHook) (void); //任务函数 用指针指向函数,不能带参数.
} TASK_COMPONENTS;
static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数
{0, 500, 500, LED0_Blink}, /* task 1 Period: 300ms */
{0, 1000, 1000, LED1_Blink}, /* task 1 Period: 600ms */
{0, 2000, 2000, LED2_Blink}, /* task 1 Period: 600ms */
{0, 10, 10, KEY_Task}, /* task 1 Period: 600ms */
};
u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);
void main(void)
{
//-----------------------------------------------------------------------------
Sys_init(); //系统初始化
//----------------------------------------------------------------
//----------1毫秒@24.000MHz------定时器初始化--
TM0PS = 0x00; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初始值
TH0 = 0xF8; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
while(1)
{
u8 i;
for(i=0; i<Tasks_Max; i++)
{
if(Task_Comps.Run) /* If task can be run */
{
Task_Comps.Run = 0; /* Flag clear 0 */
Task_Comps.TaskHook(); /* Run task */
}
}
}
}
void Timer0_Isr(void) interrupt 1 //1MS执行一次
{
u8 i;
for(i=0; i<Tasks_Max; i++)
{
if(Task_Comps.TIMCount) /* If the time is not 0 */
{
Task_Comps.TIMCount--; /* Time counter decrement */
if(Task_Comps.TIMCount == 0) /* If time arrives */
{
/*Resume the timer value and try again */
Task_Comps.TIMCount = Task_Comps.TRITime;
Task_Comps.Run = 1; /* The task can be run */
}
}
}
}
scpcw
发表于 2025-2-21 22:05:08
第九集 数码管
第十集 虚拟键盘LED和数码管
第十一集 矩阵按键
这几集放在一起学习,一起练习吧。它们都是为了单机的调试服务。也是简单常用的输入输出设备。
如果需要按从高到低位发送1字节数据的情况
可以用如下算法,最高效率,主要用于串行方式通讯,I2C是这样。
u8 i;
u8 Dat=0xFF;
for(i=0,i<8,i++)
Dat += Dat; //等同Dat=Dat<<1 ,位移比加法多一条汇编指令,最高位进入CY(程序状态字寄存器)PSW进位标志位
HC595_SER=CY; //引脚只要发送CY标志就可以了,但要注意后面其它操作不能影响进位标志
HC595_SRCLK=1;
HC595_SRCLK=0;
}
下面是易读版
u8 i;
u8 Dat;
for (i = 0; i < 8; i++) {
HC595_SER = (Dat & 0x80) ? 1 : 0;// 直接输出最高位
Dat <<= 1; // 左移一位
}
下面是入门版,效率最低。
u8 i;
u8 Dat;
for (i = 0; i < 8; i++) {
HC595_SER = (Dat&0x80)>>7; //不解释
HC595_SRCLK=1;
HC595_SRCLK=0;
Dat = Dat<<1; // 左移一位
}
scpcw
发表于 2025-2-23 09:58:49
还在等实验箱,今天把我的STC8也拿出来,也为9,10,11集的练习做一下准备。两套系统都做一下。
之前的STC8核心开发板,用的一个USB转ttl下载数据。核心板上P30 P31没有二极管和电阻。下发数据复位时,只能四条线一起怼。
后来我在GND上接了一个开关,好象可以下载了。但有40%概率会不成功。
今天我按芯片手册找了一个二级管和电阻,想按规矩改一下。
开始找了一个1N1007二极管,但是压降太大了,不能识别到。
后来又找了一个FR107,我看参数应该能代替1N5819。、
不知道是哪里的原因,我在3v3上接了一个开关,不能下载。我只能不用这个电源。只保留GND,RXD,TXD三根线。
然后在核心板用面包板上面的3.3V供电。通过对面包板上的电源开关,下载就很顺了。
也研究了一下USB下载
STC8支持USB下载,不支持USB仿真,就没有去实现这个功能了。
scpcw
发表于 2025-2-23 10:35:44
今天把《第8集定时器周期性调渡任务》移植到STC8上面,还要把串口也要初始化出来。
先把后面的串口通讯预习一下.后面好象有这个课.
void UartInit() //115200bps@11.0592MHz 串口1 定时器1
{
/*顺序: SCON(串口控制器) //后面都是定时器控制
->AUXR(定时器辅助寄存器)控制是否分频1T 12T
->TMOD(定时器模式)
->TL0,TL1定时器计数寄存器计算波特率
->定时器开始计时TCON 里的TR1 第6位
->串口使能ES=1;
*/
SCON = 0x50; //串口控制寄存器, 串口1:SCON 串口2:S2COM
//b7 b6 0 1 可变波特率8位数据方式 b4 1充许接收 01010000 后面4位设0,细节后面再研究.
//---------------------------------------------------------------
AUXR |= 0x40; //定时器时钟1T模式
// b7位,定时器0 12T模式0 不分频1 //b6位定时器0 12T模式0 不分频1
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 //最后1位0使用定时器1 最后1位1使用定时器2
//上面一句可以直接用40或41
//AUXR = 0x40; // 0x41为使用定时器2
TMOD &= 0x0F; //设置 对高4位定时器1全设0,低4位定时器0不改动;
TL1 = BRT; //使用此变量可以让系统主频与串口频率无关.
TH1 = BRT >> 8; //#define FOSC 11059200UL
//#define BRT (65536 - FOSC / 115200 / 4) 这个公式用于1T模式
//#define BRT (65536 - FOSC / 12 / 115200 / 32) 这个公式用于12T模式
TR1 = 1; //定时器1开始计时 TCON 定时器控制器,T1举出中断标志和定时器运行控制位
//TF1和TR1是TCON最高7,6位 TF0和TR0是5,4位
//----------------------------------------------
ES = 1; //串口中断使能,如果不用串口中断可以不用使能
EA = 1; //全局中断使能
busy = 0; //例程添加的一个变量,可忽略
}
scpcw
发表于 2025-2-23 21:37:16
数码管代码敲好了.
scpcw
发表于 2025-2-24 07:30:13
矩阵键盘
我的矩阵键盘模块,请指正!
#include "MatrixKey.h"
u8 key_num=0xff;
void MatrixKey(void)
{
bit m,n,o,p;
ROW1 = 1; //先判断横,所以先置高电平先让她稳定
ROW2 = 1;
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
m=ROW1; //添加中间变量是为了稳定性
n=ROW2; //实测没有中间变量,再切换电平后,电平未稳定,下面的按键扫描有误
if( m != n)
{
if( m ) key_num = 4; //如果1行高电平,就是按了2行,所以为2行第一个键码4
if( n)key_num = 0;
COL1 = 1; //下面是扫描纵列,所以先改纵列电平
COL2 = 1;
COL3 = 1;
COL4 = 1;
ROW1 = 0;
ROW2 = 0;
m=COL1;
n=COL2;
o=COL3;
p=COL4;
//if( m==0 )key_num=key_num;
if( n == 0 ) key_num = key_num + 1;
if( o == 0 ) key_num = key_num + 2;
if( p == 0 ) key_num = key_num + 3;
}else key_num=0xff;
}