51匯流排方式獲取adc0809數值
最近微控制器有一個實驗挺有意思的,使用51微控制器以匯流排的方式讀取adc0809的資料
先補充點關於微控制器匯流排的預備知識,我一開始不瞭解匯流排的時候做這個實驗也是很懵逼的。
微控制器的三匯流排結構
51微控制器有三條匯流排:資料匯流排、地址匯流排、控制匯流排
從圖中可以看出,8位資料匯流排由P0組成,16位地址匯流排由P0和P2組成,控制匯流排由P3和相關引腳組成
採用匯流排的方式可以簡化程式設計,節省I/O口,便於外設擴充套件
但是資料口和地址口在P0是怎麼複用的呢,這就需要看到時序了
從圖中可以看出,P0口是資料/地址分時複用的,這是P0口內部的複用結構完成的
實操練習
51微控制器與adc0809接線原理圖如下
解釋電路
P2.7口用作adc0809的選擇線
P0.0~P0.2所接的A B C是adc0809的IN0通道選擇線
接下來就是計算adc0809的地址了
P2 P0
0xxx xxxx xxxx x000
因此地址為0x7ff8
遇到的問題
本來應該顯示5v的位置只顯示1.144v,而且在電阻增大的過程中,顯示的值先減小後增大又減小,具體情況如圖
實在沒有辦法的情況下,借別的同學的程式碼來看,沒發現自己的程式在時序、地址上的錯誤。
琢磨了微控制器的數值變換的現象後,突然覺得是不是儲存ad轉換數值的變數溢位了,然後就發現我的變數型別是int,而別人的變數型別是long int
在將儲存ad轉換的變數型別修改過後,程式就執行正常了
程式程式碼
#include <reg51.h>
#include <absacc.h>
typedef unsigned char uchar;
typedef unsigned int uint8;
typedef unsigned long int uint16;
uchar led_mod[] = { 0x3f,0x06,0x5b,0x4f, //!< 數碼管編碼
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
#define AD_IN0 XBYTE [0x7ff8]
sbit EOC = P3^5;
sbit CLK = P3^3;
sbit seg1 = P2^0;
sbit seg2 = P2^1;
sbit seg3 = P2^2;
sbit seg4 = P2^3;
uint16 adc_data = 0; //> 儲存ad轉換結果
/**
* @brief 延遲函式
*
*/
void delay_ms(uint8 time)
{
uint8 j;
for (; time>0; time--)
{
for(j=114; j>0; j--);
}
}
/**
* @brief 定時器初始化
*
*/
void timer_init(void)
{
TMOD |= 0x02;
TH0 = 200; //> 產生方波週期2us
TL0 = 200;
ET0 = 1;
TR0 = 1;
}
/**
* @brief 數碼管動態顯示函式
*
*/
void display(void)
{
adc_data = adc_data*1000/51; //> 解析度為5/256約為1/51
P1 = 0x00;
P1 = led_mod[adc_data/1000]|0x80;
seg1 = 0;
delay_ms(2);
seg1 = 1;
P1 = 0x00;
P1 = led_mod[(adc_data%1000)/100];
seg2 = 0;
delay_ms(2);
seg2 = 1;
P1 = 0x00;
P1 = led_mod[(adc_data%100)/10];
seg3 = 0;
delay_ms(2);
seg3 = 1;
P1 = 0x00;
P1 = led_mod[adc_data%10];
seg4 = 0;
delay_ms(2);
seg4 = 1;
}
void main()
{
timer_init();
EA = 1;
while(1)
{
AD_IN0 = 0;
while(EOC == 0);
adc_data = AD_IN0;
display();
}
}
/**
* @brief 產生時鐘週期
*
*/
void timer0() interrupt 1
{
CLK = ~CLK;
}
相關文章
- 匯流排
- CAN匯流排取樣點測試
- 事件匯流排事件
- 6.匯流排
- I2C匯流排 | I2C匯流排介紹
- 將Abp預設事件匯流排改造為分散式事件匯流排事件分散式
- js獲取數字陣列最大值的幾種方式JS陣列
- gitlab cicd中獲取tag值的方式Gitlab
- Can匯流排介紹
- Vue 事件中央匯流排Vue事件
- Vue事件匯流排(EventBus)Vue事件
- ARM 匯流排協議協議
- Solon2 分散式事件匯流排的技術價值?分散式事件
- PCI匯流排基本概念
- 序列匯流排的學習
- CAN匯流排原理_學習
- I2C 匯流排
- 計算匯流排頻寬
- 大資料匯流排(DataHub)大資料
- 如何獲取變數token的值變數
- 如何獲取變數 token 的值變數
- C#獲取URL引數值C#
- 數倉實踐:匯流排矩陣架構設計矩陣架構
- 我最喜歡的程式之間通訊方式-訊息匯流排
- 企業服務匯流排ESB
- Flutter中的事件匯流排(EventBus)Flutter事件
- SpringCloud(六)Bus訊息匯流排SpringGCCloud
- SOFA 原始碼分析— 事件匯流排原始碼事件
- 手寫訊息匯流排LiveDataBusLiveData
- Oracle 獲取整數方式程式碼整理Oracle
- C# 解析獲取Url引數值C#
- JavaScript 獲取 url 傳遞引數值JavaScript
- LLM-kimi:BMS-CAN匯流排
- MACH SYSTEMS—匯流排介面轉換工具Mac
- 自己動手寫事件匯流排(EventBus)事件
- 如何通過WinDbg獲取方法引數值
- JavaScript獲取url傳遞的引數值JavaScript
- Spring Boot EL獲取配置檔案中的值的方式Spring Boot