- 打卡等级:以坛为家II
- 打卡总天数:493
- 最近打卡:2025-05-01 08:31:58
荣誉版主
- 积分
- 3476
|
发表于 2024-4-21 09:38:09
|
显示全部楼层
本帖最后由 浦江一水 于 2024-4-21 09:39 编辑
感谢楼上朋友对本帖的浏览和阅读。
关于TM1638模块的本实验, 虽然不是在STC8G中实验的, 但是相信原理应该是相同的,都是纯IO口的读写操作。
源码是自己写的, 连同工程文件, 仅供参考。本自制洞洞实验板,本来也有四个按键,注意与TM1638模块上按键的区别……
04-TestTM1638.rar
(34.02 KB, 下载次数: 149)
主程序体现了本实验的动作内容,可看注释……
//========================================================
// 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[20];
//非精确延时...
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模块在实验板上的引脚定义
sbit STB=P4^5; //片选
sbit CLK=P2^7; //时钟
sbit DIO=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.C 8键8数码管8LED模块 函数实现
//****************************************************************************
#include "STC32G.H"
#include <stdio.h>
#include <string.h>
#include "TM1638.H"
//命令字
#define DATA_CMD 0x40
#define DISP_CMD 0x80
#define ADDR_CMD 0xC0
//共阴数码管显示字符表 (共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[4],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[ii])
{ 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 *********************************************************************************
|
|