|
用模塊資料+豆包AI+自己修改生成的C代碼,調(diào)試OK,奉獻(xiàn)給大家
TM1650 4KEY4LED計數(shù)器(總減+移位+減1+加1)C代碼
//TM1650四按鍵四數(shù)碼管數(shù)據(jù)調(diào)整實驗OK
//功能:按TM1650四按鍵四LED數(shù)碼管模塊第二個鍵,個位閃爍,第三個鍵減小,第四個鍵增大。十位以上以此類推。
//第一個按鍵為4位LED總顯示數(shù)值遞減計數(shù)
//主程序
#include<reg52.h>
#include<intrins.h>
#include"tm1650.h"
#define uchar unsigned char
#define uint unsigned int
// 新增全局變量聲明
bit flash_flag; // 閃爍標(biāo)志
uchar flash_counter; // 閃爍計時器
uchar adjust_mode = 0; // 新增調(diào)整模式狀態(tài)
uchar digits[4] = {0,0,0,0}; // 新增數(shù)值存儲數(shù)組
uint combined_value; // 4位LED顯示總數(shù)值
// 顯示編碼表(帶小數(shù)點控制位)
uchar CODE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
// 定時器初始化(新增完整函數(shù))
void Timer0_Init() {
TMOD |= 0x01; // 模式1
TL0 = 0x18; // 1ms定時
TH0 = 0xFC;
ET0 = 1; // 中斷使能
TR0 = 1;
EA = 1;
}
// 定時器中斷服務(wù)(新增完整實現(xiàn))
void Timer0_ISR() interrupt 1
{
static uint counter = 0;
TH0 = 0xFC; // 重裝初值
TL0 = 0x18;
if(++counter >= 500) { // 500ms周期
flash_flag = !flash_flag;
counter = 0;
}
}
// 顯示更新函數(shù)(優(yōu)化小數(shù)點處理)
void Update_Display()
{
uchar seg_data;
// 千位(地址0x68)
seg_data = (adjust_mode==4 && flash_flag) ? 0x00 : CODE[digits[0]];
TM1650_Set(0x68, seg_data | (adjust_mode==4 ? 0x80 : 0x00));
// 百位(地址0x6A)
seg_data = (adjust_mode==3 && flash_flag) ? 0x00 : CODE[digits[1]];
TM1650_Set(0x6A, seg_data | (adjust_mode==3 ? 0x80 : 0x00));
// 十位(地址0x6C)
seg_data = (adjust_mode==2 && flash_flag) ? 0x00 : CODE[digits[2]];
TM1650_Set(0x6C, seg_data | (adjust_mode==2 ? 0x80 : 0x00));
// 個位(地址0x6E)
seg_data = (adjust_mode==1 && flash_flag) ? 0x00 : CODE[digits[3]];
TM1650_Set(0x6E, seg_data | (adjust_mode==1 ? 0x80 : 0x00));
// 計算總數(shù)值
combined_value = digits[0] * 1000 + digits[1] * 100 + digits[2] * 10 + digits[3];
}
// 按鍵處理(增加邊界保護(hù))
void Process_Key(uchar key)
{
static uchar last_key = 0;
if(key == last_key) return;
// 模式切換鍵處理
if(key == 0x54) // 0x54是TM1650的按鍵代碼之一
{
adjust_mode = (adjust_mode < 4) ? adjust_mode+1 : 0;
flash_flag = 0; // 強制顯示穩(wěn)定
}
if(key == 0x5c) // 0x5c是TM1650的按鍵代碼之一
{
if(combined_value > 0) {
combined_value--;
// 將總數(shù)值拆分為各個數(shù)位
digits[0] = combined_value / 1000;
digits[1] = (combined_value / 100) % 10;
digits[2] = (combined_value / 10) % 10;
digits[3] = combined_value % 10;
}
}
// 數(shù)值調(diào)整(帶范圍限制)
if(adjust_mode > 0)
{
uchar *p = &digits[4 - adjust_mode];
if(key == 0x4C) *p = (*p - 1 + 10) % 10; // 循環(huán)減,0x4c是TM1650的按鍵代碼之一
if(key == 0x44) *p = (*p + 1) % 10; // 循環(huán)加,0x44是TM1650的按鍵代碼之一
}
last_key = key;
}
// 主函數(shù)(修正初始化邏輯)
void main()
{
Timer0_Init();
TM1650_Set(0x48, 0x51); // 顯示控制:5級亮度
Update_Display(); // 初始化顯示
while(1)
{
Process_Key(Scan_Key());
Update_Display();
}
}
//TM1650 C文件
#include<reg52.h>
#include"tm1650.h"
void Delay_us(uint i) //us延時
{
for(;i>0;i--)
{
_nop_();
// _nop_();
// _nop_();
// _nop_();
// _nop_();
}
}
void I2CStart(void) //開始信號
{
CLK_H;
DIO_H;
Delay_us(5);
DIO_L;
}
void I2Cask(void) //ACK信號
{
uchar timeout = 1;
CLK_H;
Delay_us(5);
CLK_L;
while((DIO)&&(timeout<=100))
{
timeout++;
}
Delay_us(5);
CLK_L;
}
void I2CStop(void) //停止信號
{
CLK_H;
DIO_L;
Delay_us(5);
DIO_H;
}
void I2CWrByte(uchar oneByte) //寫一個字節(jié)高位在前,低位在后
{
uchar i;
CLK_L;
Delay_us(1);
for(i=0;i<8;i++)
{
oneByte = oneByte<<1;
DIO = CY;
CLK_L;
Delay_us(5);
CLK_H;
Delay_us(5);
CLK_L;
}
}
uchar Scan_Key(void) // 按鍵掃描
{
uchar i;
uchar rekey;
I2CStart();
I2CWrByte(0x49);//讀按鍵命令
I2Cask();
//DIO_H;
for(i=0;i<8;i++)
{
CLK_H;
rekey = rekey<<1;
if(DIO)
{
rekey++;
}
Delay_us(5);
CLK_L;
}
I2Cask();
I2CStop();
return(rekey);
}
void TM1650_Set(uchar add,uchar dat) //數(shù)碼管顯示
{
//寫顯存必須從高地址開始寫
I2CStart();
I2CWrByte(add); //第一個顯存地址
I2Cask();
I2CWrByte(dat);
I2Cask();
I2CStop();
}
//TM1650 C文件
#ifndef __TM1650_H__
#define __TM1650_H__
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CLK = P1^0;
sbit DIO = P1^1;
#include<reg52.h>
#define CLK_H CLK = 1
#define CLK_L CLK = 0
#define DIO_H DIO = 1
#define DIO_L DIO = 0
void TM1650_Set(uchar add,uchar dat);
uchar Scan_Key(void);
#endif
|
評分
-
查看全部評分
|