当前位置:网站首页>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
边栏推荐
- Stick to the big screen UI, finereport development diary
- Small and medium-sized projects to achieve certification and authorization of hand filter
- Some experience of exercise and fitness
- Zzuli:1061 sequential output of digits
- Spark概述
- [personal test] copy and paste code between VirtualBox virtual machine and local
- 1035 Password
- ThreadLocal memory leak
- php数组转化为xml
- Oled12864 LCD screen
猜你喜欢

OLED12864 液晶屏

软件测试基础篇

我所理解的DRM显示框架

Reading notes of cgnf: conditional graph neural fields
![[paper translation] gcnet: non local networks meet squeeze exception networks and beyond](/img/7a/718162d08796f70251511101b3a61b.png)
[paper translation] gcnet: non local networks meet squeeze exception networks and beyond

Technologists talk about open source: This is not just using love to generate electricity

文件包含漏洞(二)

idea开发工具常用的插件合集汇总
![[personal test] copy and paste code between VirtualBox virtual machine and local](/img/ce/eaf0bd9eff6551d450964da72e0b63.jpg)
[personal test] copy and paste code between VirtualBox virtual machine and local

ThreadLocal memory leak
随机推荐
RGB 无限立方体(高级版)
Stick to the big screen UI, finereport development diary
[paper translation] gcnet: non local networks meet squeeze exception networks and beyond
Lingyunguang rushes to the scientific innovation board: the annual accounts receivable reaches 800million. Dachen and Xiaomi are shareholders
深度学习分类网络--VGGNet
500. 键盘行
Basic use of form
Some experience of exercise and fitness
cookie插件和localForage离线储存插件
JWT工具类
Regular expression summary
memcached安装
来啦~ 使用 EasyExcel 导出时进行数据转换系列新篇章!
servlet的web.xml配置详解(3.0)
GRBL 软件:简单解释的基础知识
php数组转化为xml
Lambda 表达式 和 方法引用
Oled12864 LCD screen
[leetcode] day92 container with the most water
idea開發工具常用的插件合集匯總