当前位置:网站首页>STC8H8K系列匯編和C51實戰——數碼管顯示ADC、按鍵串口回複按鍵號與ADC數值
STC8H8K系列匯編和C51實戰——數碼管顯示ADC、按鍵串口回複按鍵號與ADC數值
2022-07-02 05:53:00 【不知何人】
數碼管顯示ADC、串口顯示ADC按鍵與數值
一、題目
實現了通過與通道ADC0相連的16個ADC按鍵引起的模擬電壓信號變化的測量,用實驗箱上的數碼管高2比特顯示鍵碼,低4比特顯示AD值。使用串口1在主機串口助手上顯示鍵值和轉換結果數值, 顯示格式為: 鍵值:對應ADC結果。繼續按鍵回車換行,以同樣格式顯示下一個鍵值及其ADC結果。
二、代碼
main函數
//高2比特顯示鍵碼,低4比特顯示AD值
#include<stc8h.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
bit busy;
u8 key=0;
uchar cnt1ms=0;
uint ad_volume=0;
#define ADC_OFFSET 64
uchar KeyCode=0;
void CalculateAdcKey(uint adc);
uint Get_ADC12bitResult(uchar channel); //channel = 0~7
#define font_PORT P6 //定義字形碼輸出端口
#define position_PORT P7 //定義比特控制碼輸出端口
uchar code LED_SEG[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x40,0x79,0x24,0x30,0x19,0x12d,0x02,0x78,0x00,0x10,0xbf };
//定義"0、1、2、3、4、5、6、7、8、9","A、B、C、D、E、F"以及"滅"的字形碼
//定義"0、1、2、3、4、5、6、7、8、9"(含小數點)的字符以及“-”的字形碼
uchar code Scan_bit[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf, 0xbf, 0x7f}; //定義掃描比特控制碼
uchar data Dis_buf[]={
16,16,16,16,16,16,16,0}; //定義顯示緩沖區,最低比特顯示"0",其它為"滅"
void gpio() //gpio初始化為准雙向口,剛開始除了P30,P31其他均為高阻態
{
P0M1 = 0x00; P0M0 = 0x00; //設置為准雙向口
P1M1 = 0x00; P1M0 = 0x00; //設置為准雙向口
P2M1 = 0x00; P2M0 = 0x00; //設置為准雙向口
P3M1 = 0x00; P3M0 = 0x00; //設置為准雙向口
P4M1 = 0x00; P4M0 = 0x00; //設置為准雙向口
P5M1 = 0x00; P5M0 = 0x00; //設置為准雙向口
P6M1 = 0x00; P6M0 = 0x00; //設置為准雙向口
P7M1 = 0x00; P7M0 = 0x00; //設置為准雙向口
}
/*---------------------------- 發送字節 ----------------------------*/
void SendData(uchar dat)
{
while (busy);
busy = 1;
SBUF = dat; //要發送的數據存入SBUF
}
/*---------------------------- 發送字符串函數 ----------------------------*/
void SendString(uchar *s)
{
while (*s !='\0') //字符串被讀取完才停止
{
SendData(*s++); //每發送完一個字節s++
}
}
void Timer0Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0x40; //設置定時初值
TH0 = 0xA2; //設置定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
}
/*――――――――――延時函數――――――――――――*/
void Delay1ms() //@24.000MHz
{
unsigned char i, j;
_nop_();
i = 32;
j = 40;
do
{
while (--j);
} while (--i);
}
void Delay500us() //@24.000MHz
{
unsigned char i, j;
i = 16;
j = 147;
do
{
while (--j);
} while (--i);
}
/*――――――――――顯示函數――――――――――――*/
void LED_display(void)
{
uchar i;
for(i=0;i<8;i++)
{
position_PORT =0xff; font_PORT =LED_SEG[Dis_buf[i]]; position_PORT = Scan_bit[7-i]; Delay500us();
}
}
/*――――――――――串口初始化――――――――――――*/
void InitUART(void)
{
SCON = 0x50; //8比特數據
P_SW1= P_SW1 & 0x3F;
AUXR |= 0x40; //定時器1T模式
AUXR &= 0xFE;
TMOD &= 0x0F;
TMOD |= 0x20; //8比特自動重裝載模式
TL1 = 0xDC; //
TH1 = 0xDC;
TR1 = 1; //開啟定時器1
ES = 1; //開啟串口中斷
EA = 1;
}
/**********************************************/
void main(void)
{
uint j;
gpio();
ADCCFG=ADCCFG|0x20; //RESFMT比特置1,存儲結果右對齊
ADC_CONTR = 0x80; //打開AD轉換模塊電源
P1M1=P1M1|0x01; //P1口設為高阻態
Timer0Init();
InitUART();
ET0 = 1; //Timer0 interrupt enable
TR0 = 1; //Tiner0 run
EA = 1; //打開總中斷
while(1)
{
Dis_buf[4] = ad_volume / 1000%10; //顯示ad值
Dis_buf[5] = ad_volume/100%10; //顯示ad值
Dis_buf[6] = ad_volume / 10%10; //顯示ad值
Dis_buf[7] = ad_volume % 10; //顯示ad值
Dis_buf[0] = KeyCode / 10; //顯示鍵碼
Dis_buf[1] = KeyCode % 10; //顯示鍵碼
LED_display();
if(cnt1ms >= 10) //10ms讀一次ADC
{
cnt1ms = 0;
j = Get_ADC12bitResult(0); //0通道,查詢方式做一次ADC, 返回值就是結果, == 4096 為錯誤
if(((256-ADC_OFFSET)<j)&&(j < 4096))
{
LED_display(); //去抖
LED_display();
j = Get_ADC12bitResult(0);
if(((256-ADC_OFFSET)<j)&&(j < 4096))
{
ad_volume=j;
CalculateAdcKey(j); //計算按鍵
SendData(KeyCode/10+0x30);
SendData(KeyCode%10+0x30);
SendString(": ");
SendData(ad_volume / 1000%10+0x30);
SendData(ad_volume/100%10+0x30);
SendData(ad_volume / 10%10+0x30);
SendData(ad_volume % 10+0x30);
SendString("\r\n");
Dis_buf[4] = ad_volume / 1000%10; //顯示ad值
Dis_buf[5] = ad_volume/100%10; //顯示ad值
Dis_buf[6] = ad_volume / 10%10; //顯示ad值
Dis_buf[7] = ad_volume % 10; //顯示ad值
Dis_buf[0] = KeyCode / 10; //顯示鍵碼
Dis_buf[1] = KeyCode % 10; //顯示鍵碼
LED_display();
L1: j = Get_ADC12bitResult(0);
while(((256-ADC_OFFSET)<j)&&(j < 4096)) //鍵釋放
{
LED_display();
goto L1;
}
}
}
}
}
}
/****************測量AD值*************************/
uint Get_ADC12bitResult(uchar channel) //channel = 0~15
{
ADC_RES = 0; //將轉換結果寄存器清0
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xe0) | 0x40 | channel; //先上電,再開始,再選擇通道
_nop_(); _nop_(); _nop_(); _nop_();//第一次開始的時候需要等待電路穩定
while((ADC_CONTR & 0x20) == 0) ; //等待ADC完成
ADC_CONTR &= ~0x20; //清除ADC結束標志
return (((uint)ADC_RES << 8) | ADC_RESL );
}
/***************** ADC鍵盤計算鍵碼 ********************************/
void CalculateAdcKey(uint adc)
{
uchar i;
uint j=256;
for(i=1; i<=16; i++)
{
if((adc >= (j - ADC_OFFSET)) && (adc <= (j + ADC_OFFSET))) break; //判斷是否在偏差範圍內
j += 256;
}
if(i < 17) KeyCode = i; //保存鍵碼
}
/********************** Timer0 1ms中斷函數 ************************/
void timer0 (void) interrupt 1
{
cnt1ms++;
}
/*---------------------------- UART 中斷 -----------------------------*/
void Uart() interrupt 4 using 1
{
LED_display();
if (RI)
{
RI = 0; //接收到字符後,RI清0
}
if (TI)
{
TI = 0; //發送完字符後TI清0
busy = 0; //發送完一個字符後busy清0
}
}
LED_display函數
// 以下為LED_display.c
#include <stc8h.h>
#include <intrins.h>
#define font_PORT P6 //定義字形碼輸出端口
#define position_PORT P7 //定義比特控制碼輸出端口
uchar code LED_SEG[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x40,0x79,0x24,0x30,0x19,0x12d,0x02,0x78,0x00,0x10,0xbf };
//定義"0、1、2、3、4、5、6、7、8、9","A、B、C、D、E、F"以及"滅"的字形碼
//定義"0、1、2、3、4、5、6、7、8、9"(含小數點)的字符以及“-”的字形碼
uchar code Scan_bit[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf, 0xbf, 0x7f}; //定義掃描比特控制碼
uchar data Dis_buf[]={
16,16,16,16,16,16,16,0}; //定義顯示緩沖區,最低比特顯示"0",其它為"滅"
/*――――――――――延時函數――――――――――――*/
void Delay1ms() //@24.000MHz
{
unsigned char i, j;
_nop_();
i = 32;
j = 40;
do
{
while (--j);
} while (--i);
}
/*――――――――――顯示函數――――――――――――*/
void LED_display(void)
{
uchar i;
for(i=0;i<8;i++)
{
position_PORT =0xff; font_PORT =LED_SEG[Dis_buf[i]]; position_PORT = Scan_bit[7-i]; Delay1ms ();
}
}
LED_display.h頭文件
#ifndef __LED_DISPLAY_H__
#define __LED_DISPLAY_H__
void Delay1ms();
void LED_display(void);
uchar code LED_SEG[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x40,0x79,0x24,0x30,0x19,0x12d,0x02,0x78,0x00,0x10,0xbf };
//定義"0、1、2、3、4、5、6、7、8、9","A、B、C、D、E、F"以及"滅"的字形碼
//定義"0、1、2、3、4、5、6、7、8、9"(含小數點)的字符以及“-”的字形碼
uchar code Scan_bit[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf, 0xbf, 0x7f}; //定義掃描比特控制碼
uchar data Dis_buf[]={
16,16,16,16,16,16,16,0}; //定義顯示緩沖區,最低比特顯示"0",其它為"滅"
#end if
非常感謝各比特觀看!!!
系列文章——STC8H8K系列匯編51實戰
基於ESP8266與STC單片機的天氣時鐘(包括DS18B20、TFT、串口、外部中斷、ESP8266、STC、API等)
STC8H8K系列匯編和C51實戰——實現鍵控不同方式數碼管動態顯示(C51版與匯編版)
STC8H8K系列匯編和C51實戰——開關控制定時器秒錶(C51版)
STC8H8K系列匯編和C51實戰——開關控制定時器秒錶(匯編版)
STC8H8K系列匯編和C51實戰——雙中斷控制定時器流水燈
STC8H8K系列匯編和C51實戰——秒倒計時器(可自行設定初值)(51版)
STC8H8K系列匯編和C51實戰——按鍵允許按鍵計數(51版)
STC8H8K系列匯編和C51實戰——按鍵允許按鍵計數(匯編版)
STC8H8K系列匯編和C51實戰——按鍵允許按鍵計數(定時器去抖動51版)
STC8H8K系列匯編和C51實戰——按鍵允許按鍵計數(利用下降沿中斷控制)
STC8H8K系列匯編和C51實戰——計算機串口控制單片機LED
边栏推荐
- 1037 Magic Coupon
- 3D 打印机 G 代码命令:完整列表和教程
- VSCode paste image插件保存图片路径设置
- TypeScript的泛型和泛型约束
- Minimum value ruler method for the length of continuous subsequences whose sum is not less than s
- 如何写出好代码 — 防御式编程指南
- Appnuim environment configuration and basic knowledge
- 1036 Boys vs Girls
- Vscode paste image plugin saves image path settings
- Zzuli: maximum Convention and minimum common multiple
猜你喜欢
How vite is compatible with lower version browsers
Can't the dist packaged by vite be opened directly in the browser
With an amount of $50billion, amd completed the acquisition of Xilinx
GRBL 软件:简单解释的基础知识
Mathematical statistics and machine learning
15 C language advanced dynamic memory management
Summary of MySQL constraints
How to write good code - Defensive Programming Guide
Spark概述
软件测试基础篇
随机推荐
如何写出好代码 — 防御式编程指南
PHP inner class name is the same as the inner class method name
Unity Shader 学习笔记(3)URP渲染管线带阴影PBR-Shader模板(ASE优化版本)
JS determines whether the mobile terminal or the PC terminal
Oled12864 LCD screen
Mathematical statistics and machine learning
[paper translation] gcnet: non local networks meet squeeze exception networks and beyond
Regular expression summary
Spark概述
File contains vulnerabilities (II)
Conglin environmental protection rushes to the scientific and Technological Innovation Board: it plans to raise 2billion yuan, with an annual profit of more than 200million yuan
2022-2-14 learning xiangniuke project - section 23, section 5, development login and exit functions
文件包含漏洞(二)
PHP gets CPU usage, hard disk usage, and memory usage
[technical notes-08]
vite如何兼容低版本浏览器
Zzuli:1067 faulty odometer
【論文翻譯】GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond
测试 - 用例篇
Vite打包后的dist不能直接在浏览器打开吗