浦江一水
发表于 2023-11-15 20:05:35
阶段性的学习实验小结
自从用洞洞板做了STC32G12K128(DIP40)实验板以来,做了一些实验,阶段性的小结罗列一下:
1,STC单片机 IO端口电平控制--“跑马灯” 程序练习,主要目的是学习掌握工程文件框架的基本建设;
2,实验对LCD1602字符型显示屏的控制显示输出,对四键八值的输入练习;
3,实验IIC单色OLED(128*64)点阵显示屏的控制,实现中西文混合显示;
4,实验 STC32G12K128 对彩色显示屏(128*160)控制显示,实现中西文混合显示, 实验12位ADC转换;
5,实验 驱动TM1638数码管模块,实现用三个IO端口,控制8个键输入,8个LED发光管亮灭控制,8位数码管数字和字符串显示。
在学习实验过程中,购买了 STC USB Link1D仿真器、一箭双雕转串口、USB转串口等等工具。
由于没有充分了解和掌握STC USB Link1D仿真器和一箭双雕转串口工具对STC32G12K128仿真的有关知识。所以在整个实验过程中,仅仅依靠USB转串口的工具,反复下载调试。
没有发挥STC USB Link1D仿真器和一箭双雕转串口工具的优势作用,给研究算法调试编程,带来了很大的困难。降低了学习实验的效率。
最近经反复观看论坛前辈们的视频教程和技术帖子,初步感悟了使用STC USB Link1D仿真器的基本知识,准备下一阶段学习实验中,让这些调试工具发挥应有的作用。
由于申请的STC32G12K128实验箱,已经收到。在此向STC国芯表示由衷感谢。
下一阶段的学习实验,自己也已淘购配置了单色彩色显示屏, 学习实验将在实验箱中开展,将学习更多的STC单片机编程知识。
自制的洞洞实验板,也是立下了汗马功劳,已完成了它的历史使命,也是自己学习过程的一个见证。
在国芯论坛留下一笔,也许会有坛友记得它曾经的存在。
小正
发表于 2024-3-23 18:04:58
照搬程序但字符串显示不正确是为什么呜呜
soma
发表于 2024-3-24 00:03:00
各种各样的屏真多
wan123456
发表于 2024-3-24 06:20:26
不知道为啥非要251…
浦江一水
发表于 2024-3-24 08:56:03
楼上朋友,我的理解是:
由于:微处理器位数不同, 指令集不同,编译器不同。
因此:
STC8H8K64U 使用C51 。
STC32G12K128 使用C251。
不能兼容。
QW123
发表于 2024-3-26 09:25:52
这帖子不给加精一下?收藏学习中,谢谢楼主无私共享,关键还注释这么详细
浦江一水
发表于 2024-3-27 15:21:47
QW123 发表于 2024-3-26 09:25
这帖子不给加精一下?收藏学习中,谢谢楼主无私共享,关键还注释这么详细 ...
感谢您的浏览阅读和谬赞,我们共同学习STC单片机的应用。
cadplus
发表于 2024-4-20 15:26:05
浦江一水 发表于 2023-11-12 20:59
关于STC32G12K128实验板驱动TM1638数码管模块的实验
源码可以分享吗?
用在STC8G中,LED和数码管正常,S1-S8不可靠,有误动作不敢用
浦江一水
发表于 2024-4-21 09:38:09
本帖最后由 浦江一水 于 2024-4-21 09:39 编辑
cadplus 发表于 2024-4-20 15:26
源码可以分享吗?
用在STC8G中,LED和数码管正常,S1-S8不可靠,有误动作不敢用 ...
感谢楼上朋友对本帖的浏览和阅读。
关于TM1638模块的本实验, 虽然不是在STC8G中实验的, 但是相信原理应该是相同的,都是纯IO口的读写操作。
源码是自己写的, 连同工程文件, 仅供参考。本自制洞洞实验板,本来也有四个按键,注意与TM1638模块上按键的区别……
主程序体现了本实验的动作内容,可看注释……
//========================================================
// TM1638_8键8LED8数码管模块 实验程序
// 驱动:TM1638
// 基于: STC32G12K128芯片实验板编程 主频选择: 22.118400MHz
// 整理:编程: 浦晓明(浦江一水) 2023-11...
//========================================================
#include "STC32G.H"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "KEY4_IO.H"
#include "TM1638.H"
//4LED
sbit LED0= P2^0;//运行指示
sbit LED1= P2^1;//运行指示
sbit LED2= P2^2;//运行指示
sbit LED3= P2^3;//运行指示
unsigned char k,TMk;
char S;
//非精确延时...
void Delay_ms(unsigned int count)
{ unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<50000;j++);
}
//主程序入口
void main(void)
{ unsigned int wait=0;
unsigned char Light=0,ch=0x3F,disp=0;
float pi=3.14159;
//IO端口初始化
WTST= 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
//IO端口初始化//全部为双向口
P0M1 = 0x00; P0M0 = 0x04; //设置为准双向口: P0.2推挽输出控制背光
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
LED1=0;LED2=0;LED3=0;
LED1=1;LED2=1;LED3=1;
TM1638_Init();
TM1638_All_LED(0xFF); //8LED灯全亮
TM1638_All_LED(0x00); //8LED灯全灭
TM1638_A_LED(0,1); //指定位LED亮
TM1638_A_LED(0,0); //指定位LED灭
TM1638_A_LED(1,1); //指定位LED亮
TM1638_A_LED(1,0); //指定位LED灭
TM1638_Write_DATA( 0,0x06); //测试单个数码位显示
TM1638_Write_DATA( 2,0x5B);
TM1638_Write_DATA( 4,0x4F);
TM1638_Write_DATA( 6,0x66);
TM1638_Write_DATA( 8,0x6D);
TM1638_Write_DATA(10,0x7D);
TM1638_Write_DATA(12,0x07);
TM1638_Write_DATA(14,0x7F);
GETCH(); //按任意键继续...
TM1638_DispSTR(0,"ABCDEFGH"); //显示字符串...
GETCH(); //按任意键继续...
TM1638_DispSTR(0,"CPU-32G.H");//显示字符串...
GETCH(); //按任意键继续...
sprintf(S,"P=%07.5f",pi); //组织字符串...
TM1638_DispSTR(0,S); //显示字符串...
sprintf(S,"H-%02X C00",(unsigned int)ch); //组织字符串...
TM1638_DispSTR(0,S); //显示字符串...
TM1638_All_LED(ch); //全显
while(1)
{ if(wait==0)LED2=0; //指示程序正在运行中...
if(wait==100)LED2=1;
wait=wait<10000?wait+1:0; //循环计数...
k=0; k=RDKEY(); //读取实验板按键输入...
if(k!=0)
{ switch(k)
{ case 0x10: Light=Light<8?Light+1:8;TM1638_SetLight(Light);Delay_ms(2000); break; //控制亮度+
case 0x20: Light=Light>0?Light-1:0; TM1638_SetLight(Light);Delay_ms(2000); break; //控制亮度-
case 0x30: ch=ch<255?ch+1:0; disp=1; TM1638_All_LED(ch); break; //根据递增ch数值显示...
case 0x40: ch=ch>0?ch-1:255;disp=1; TM1638_All_LED(ch); break; //根据递减ch数值显示...
}
} Delay_ms(20);
if(disp){ sprintf(S,"H-%02X",(unsigned int)ch); TM1638_DispSTR(0,S); disp=0; }
if(wait%2500==0)
{ TMk=0; TMk=TM1638_Read_key(); //读取TM1638模块8按键输入...
if(TMk>0)
{ sprintf(S,"C%02X",(unsigned int)TMk);TM1638_DispSTR(5,S);
switch(TMk)
{ case 0x01: Light=Light<8?Light+1:8;TM1638_SetLight(Light);Delay_ms(20000);break;
case 0x02: Light=Light>0?Light-1:0; TM1638_SetLight(Light);Delay_ms(20000);break;
case 0x04: ch=ch<255?ch+1:0; disp=1; TM1638_All_LED(ch); break;
case 0x08: ch=ch>0?ch-1:255;disp=1; TM1638_All_LED(ch); break;
} Delay_ms(50000);
}
}
Delay_ms(100);
}
}
//****************************************************************************
// TM1638 8键8数码管8LED模块.头文件
//****************************************************************************
#ifndef_TM1638_H_
#define_TM1638_H_
#include"STC32G.H"
//TM1638模块在实验板上的引脚定义
sbitSTB=P4^5;//片选
sbitCLK=P2^7;//时钟
sbitDIO=P2^6;//数据
void TM1638_Init(void); //TM1638初始化函数
void TM1638_Write_DATA(unsigned char add,unsigned char DATA);//指定地址写入数据 地址:0..15
void TM1638_A_LED(unsigned char num,unsigned char flag); //单独某个LED亮灭函数,num序号 flag=0熄灭,1:点亮
void TM1638_All_LED(unsigned char LEDs); //8个LED函数同时控制 位=1;点亮 =0熄灭...
void TM1638_SetLight(unsigned char light); //设置亮度0:灭 1..8:亮度增强...
void TM1638_DispSTR(unsigned char x,char * str); //显示字符串
unsigned char TM1638_Read_key(void); //读键函数
#endif
//****************************************************************************
// TM1638.C8键8数码管8LED模块 函数实现
//****************************************************************************
#include"STC32G.H"
#include<stdio.h>
#include<string.h>
#include"TM1638.H"
//命令字
#defineDATA_CMD0x40
#defineDISP_CMD0x80
#defineADDR_CMD0xC0
//共阴数码管显示字符表 (共33字符)
unsigned char code Asc[]={ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',
'.','_','-','=','G','P','q','c','H','h','L','J','U','u','o','n',' ', };
//共阴数码管显示段码表 (对应33字符的段码)
unsigned char code Tab[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x80,0x08,0x40,0x48,0x3D,0x73,0x67,0x58,0x76,0x74,0x68,0x0E,0x3E,0x1C,0x5C,0x54,0x00,};
//****************************************************************************
// 仅供本模块调用的内部函数
//****************************************************************************
// 写一个字节函数
void TM1638_Write(unsigned char DATA) //写数据函数
{ unsigned char i;
for(i=0;i<8;i++)
{ CLK=0;
if(DATA & 0x01)DIO=1;
else DIO=0;
DATA>>=1;
CLK=1;
}
}
// 写一个命令字节
void Write_CMD(unsigned char cmd) //发送命令字
{
STB=0; //片选低(产生一个从1到0的跳变.)
TM1638_Write(cmd);
STB=1; //片选高
}
// 读取一个字节
unsigned char TM1638_Read(void) //读数据函数
{ unsigned char i;
unsigned char temp=0;
DIO=1; //设置为输入
for(i=0;i<8;i++)
{ CLK=0;
temp>>=1;
CLK=1; //数据正在时钟上升沿后读取...
if(DIO)temp|=0x80;
}
return temp;
}
//****************************************************************************
// 外部可调用函数
//****************************************************************************
// TM1638初始化函数
void TM1638_Init(void)
{ unsigned char i;
Write_CMD(0x88); //亮度 (0x88-0x8F)8级亮度可调
Write_CMD(0x40); //采用地址自动加1
STB=0; //片选中
TM1638_Write(0xC0);//设置起始地址
for(i=0;i<16;i++) //传送16个字节的数据0
TM1638_Write(0x00);
STB=1;
}
// 读取键值函数 返回0:无按键 按键1..8键值0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
unsigned char TM1638_Read_key(void)
{ unsigned char c,i,key_value=0;
STB=0;
TM1638_Write(0x42); //读键扫数据 命令
for(i=0;i<4;i++)c=TM1638_Read();//一次读4个字节
STB=1; //4个字节数据合成一个字节
for(i=0;i<4;i++)key_value|=c<<i;
return key_value; //返回键值
}
//指定地址写入数据 地址:0..15
void TM1638_Write_DATA(unsigned char add,unsigned char DATA)
{
STB=0;//片选中
//Write_CMD(0x44);
TM1638_Write(0xC0|add); //地址
TM1638_Write(DATA);
STB=1;//不选中
}
//单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
void TM1638_A_LED(unsigned char num,unsigned char flag)
{
if(flag)TM1638_Write_DATA((unsigned char)(2*num+1),1);
else TM1638_Write_DATA((unsigned char)(2*num+1),0);
}
//控制全部LED函数,LEDs表示各个位LED状态
void TM1638_All_LED(unsigned char LEDs)
{ unsigned char i;
for(i=0;i<8;i++)
{ if(LEDs&(1<<i))TM1638_Write_DATA((unsigned char)(2*i+1),1);
else TM1638_Write_DATA((unsigned char)(2*i+1),0);
}
}
//设置亮度 0:灭 1..8:亮度增强.
void TM1638_SetLight(unsigned char light)
{
switch(light)
{ case 0: Write_CMD(0x80);break; //灭
case 1: Write_CMD(0x88);break; //低亮
case 2: Write_CMD(0x89);break;
case 3: Write_CMD(0x8A);break;
case 4: Write_CMD(0x8B);break;
case 5: Write_CMD(0x8C);break;
case 6: Write_CMD(0x8D);break;
case 7: Write_CMD(0x8E);break;
case 8: Write_CMD(0x8F);break; //高亮
}
}
// (TM1638八位数码管)显示字符串函数
// 入口参数: x定位(0..7), str:需要显示的字符串(字符仅限于)
void TM1638_DispSTR(unsigned char x, char * str)
{ unsigned char ch,y,i;
if(x>=8)return; //超界..返回..
for(;x<8;x++) //从指定位置0到7
{ y=0;
for(i=0;i<33;i++) //根据字符查找对应段码
{ if(*str==Asc) // if(SS==Asc)
{ ch=Tab; //取段码
y=1; break;
} else ch=0x00; //若无对应段码则用0空替代.
}
if(y==1)
{ if(*(str+1)=='.') //如果遇小数点处理...
{ ch |= 0x80; //段码最高位置1...(加小数点)
str++;
}
TM1638_Write_DATA((unsigned char)(2*x),ch);//定位写入显示
}
str++;
if(*str=='\0')break; //字符串结束
}
}
//**** END *********************************************************************************
cadplus
发表于 2024-4-22 08:46:36
浦江一水 发表于 2024-4-21 09:38
感谢楼上朋友对本帖的浏览和阅读。
关于TM1638模块的本实验, 虽然不是在STC8G中实验的, 但是相信原理应 ...
非常感谢!
我是发觉TM1638_Read_key得到的键值不太可靠,用于DIY小机器上误动作不安全。