当前位置:网站首页>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
边栏推荐
猜你喜欢

Software testing Q & A

Unity Shader 学习笔记(3)URP渲染管线带阴影PBR-Shader模板(ASE优化版本)

Appnuim environment configuration and basic knowledge

With an amount of $50billion, amd completed the acquisition of Xilinx

Grbl software: basic knowledge of simple explanation

Can't the dist packaged by vite be opened directly in the browser

Alibaba: open source and self-developed liquid cooling data center technology

“简单”的无限魔方

Basic use of form

Cube magique infini "simple"
随机推荐
Minimum value ruler method for the length of continuous subsequences whose sum is not less than s
[golang syntax] be careful with the copy of slices
492.构造矩形
Common websites for Postgraduates in data mining
token过期自动续费方案和实现
Generics and generic constraints of typescript
Alibaba: open source and self-developed liquid cooling data center technology
Spark概述
数理统计与机器学习
Yyds dry inventory what is test driven development
Lantern Festival gift - plant vs zombie game (realized by Matlab)
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
php获取cpu使用率、硬盘使用、内存使用
OLED12864 液晶屏
Cambrian was reduced by Paleozoic venture capital and Zhike shengxun: a total of more than 700million cash
mysql的约束总结
Lambda 表达式 和 方法引用
Zzuli:1062 greatest common divisor
JS determines whether the mobile terminal or the PC terminal
mock-用mockjs模拟后台返回数据