当前位置:网站首页>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
边栏推荐
- PHP extensions
- Applet jumps to official account
- Cube magique infini "simple"
- 1035 Password
- Practice C language advanced address book design
- 中小型项目手撸过滤器实现认证与授权
- Minimum value ruler method for the length of continuous subsequences whose sum is not less than s
- DRM display framework as I understand it
- Small and medium-sized projects to achieve certification and authorization of hand filter
- GRBL 软件:简单解释的基础知识
猜你喜欢

Lantern Festival gift - plant vs zombie game (realized by Matlab)

GRBL 软件:简单解释的基础知识

Visual studio import

Practice C language advanced address book design

2022-2-14 learning xiangniuke project - section 23, section 5, development login and exit functions

RGB 无限立方体(高级版)

Cube magique infini "simple"
![[technical notes-08]](/img/52/0aff21b01ba7adbfcdb597d1aa85f9.png)
[technical notes-08]

idea開發工具常用的插件合集匯總

Spark概述
随机推荐
Online music player app
Alibaba: open source and self-developed liquid cooling data center technology
php获取cpu使用率、硬盘使用、内存使用
1037 Magic Coupon
RNN recurrent neural network
Generics and generic constraints of typescript
memcached安装
图片裁剪插件cropper.js
[golang syntax] be careful with the copy of slices
vite如何兼容低版本浏览器
ESP8266与STC8H8K单片机联动——天气时钟
Win10 copy files, save files... All need administrator permission, solution
正则表达式总结
Mathematical statistics and machine learning
Nacos 启动报错 Error creating bean with name ‘instanceOperatorClientImpl‘ defined in URL
15 C language advanced dynamic memory management
js判断移动端还是pc端
Visual studio import
我所理解的DRM显示框架
Web页面用户分步操作引导插件driver.js