數碼管作為最廉價的輸出設備,在各種自動化設備中有很大的應用,最簡單普通的顯示方式為動態刷新顯示,稱為假動態顯示,即通過分時掃描每一位,利于人眼的視覺停留現象,造成一種靜態顯示的效果,如下圖所示:
C51單片機由于運行速度很慢,在高刷新頻率下,單片機的資源耗費很厲害,這樣單片機就不可以再進行大量的計算工作,實際上,單片機在刷新時,只需要周期性的改變GPIO口的狀態就可以了,剩下的時間其實都是在空轉的狀態下,我們能不能將這個空轉的狀態拿來用呢?當然是可以的啦,這里,我們利用單片機的定時器周期地產能中斷,在中斷內進行數碼管的刷新工作,就可以將等待中斷的這個CPU時間拿來做別的事情了。
硬件電路:
代碼貼過來:
主函數
#include "shumaguan.h"
#include "timer.h"
sbit sw_jdq=P1^0;//定義一位繼電器操作
void main(void)
{
int cnt=0;//設定初值
timer_init();//初始化定時器
while(1)
{
value_now = cnt;//送初值到顯示緩存
delay(50);
cnt++;
sw_jdq=~sw_jdq;//切換繼電器狀態
if(cnt>9999)//數值超出界線,回歸最小
cnt=-999;
}
}
數碼管驅動函數
#include "shumaguan.h"
#define DType 1 //define the Digital LED type, 1: VCC in common, 0: GND in common
#if DType==1
/*--------------------------------------------------------
Set the digital LED display code
From left to right for
0,1,2,3,4,5,6,7,8,9,a.b,c,d,e,f,dp,-,
--------------------------------------------------------*/
uchar code DS_BUF[]={0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 , 0x88 ,
0x83 , 0xc6 , 0xa1 , 0x86 , 0x8e , 0x7f , 0xbf , 0xff };
#else
uchar code DS_BUF[]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6b , 0x7d , 0x07 , 0x7f , 0x6f , 0x77 ,
0x7c , 0x39 , 0x5e , 0x79 , 0x71 , 0x80 , 0x40 , 0x00 };
#endif
uchar xdata buf_sm[4]; //set display buffer
uchar frash_cnt=0;//刷新計數器
uchar wei_buf=0x10;//位輸出計數器
/*--------------------------
Compute the number from Value
value: something to display, range from -999 to 9999, suport float
--------------------------*/
void calc_sm(float value)
{
uint tmp=0;
if(value>=0)//輸入值為正數,不顯示負號
{
if(value>9999)//輸入值大于9999,顯示----
{
buf_sm[0]=17;
buf_sm[1]=17;
buf_sm[2]=17;
buf_sm[3]=17;
}
else if(value>=1000)//輸入值大于999,只顯示整數
{
tmp=value;
buf_sm[0]=tmp/1000;
buf_sm[1]=tmp%1000/100;
buf_sm[2]=tmp%100/10;
buf_sm[3]=tmp%10;
}
else if(value>=100)//顯示一位小數
{
tmp=value*10;
buf_sm[0]=tmp/1000;
buf_sm[1]=tmp%1000/100;
buf_sm[2]=(tmp%100/10)+20;
buf_sm[3]=tmp%10;
}
else if(value>=10)//顯示兩位小數
{
tmp=value*100;
buf_sm[0]=tmp/1000;
buf_sm[1]=(tmp%1000/100)+20;
buf_sm[2]=tmp%100/10;
buf_sm[3]=tmp%10;
}
else//顯示三位小數
{
tmp=value*1000;
buf_sm[0]=(tmp/1000)+20;
buf_sm[1]=tmp%1000/100;
buf_sm[2]=tmp%100/10;
buf_sm[3]=tmp%10;
}
}
else//輸入值小于0,顯示負號,其余同上
{
if((value<0)&&(value>-10))
{
tmp=value*100;
tmp=abs(tmp);
buf_sm[0]=17;
buf_sm[1]=(tmp/100)+20;
buf_sm[2]=tmp%100/10;
buf_sm[3]=tmp%10;
}
else if((value<=-10)&&(value>-100))
{
tmp=value*10;
tmp=abs(tmp);
buf_sm[0]=17;
buf_sm[1]=(tmp/100);
buf_sm[2]=tmp%100/10+20;
buf_sm[3]=tmp%10;
}
else if((value<=-100)&&(value>-1000))
{
tmp=value;
tmp=abs(tmp);
buf_sm[0]=17;
buf_sm[1]=(tmp/100);
buf_sm[2]=tmp%100/10;
buf_sm[3]=tmp%10;
}
}
}
/*
顯示部分,每執行一次,顯示的位左移一位,移到最左邊時,重新回到最右邊,開始下一次刷新。
定義有小數點的位+20,每次送斷碼,檢查大于20,段與0x7f添加小數點。
*/
void display()
{
if(frash_cnt<=3)
{
wei |=0xf0;//數碼管的消隱
if(buf_sm[3-frash_cnt]>=20)
{
duan = (DS_BUF[(buf_sm[3-frash_cnt])-20]&0x7f);//顯示小數點
}
else
duan = DS_BUF[buf_sm[3-frash_cnt]];//不顯示小數點
wei = ~wei_buf;
wei_buf <<=1;//顯示位左移一位
frash_cnt++;
}
else
{
wei |=0xf0;//數碼管的消隱
frash_cnt=0;
wei_buf=0x10;//顯示位回到最右邊
}
}
/*
數碼管自用延時
*/
void delay(uint i)
{
uchar j;
for(;i>0;i--)
for(j=0;j<120;j++);
}
數碼管頭文件
#ifndef _shumaguan_h_
#define _shumaguan_h_
#include "math.h"
#include "reg52.h"
#define duan P0
#define wei P2
#define uchar unsigned char
#define uint unsigned int
extern uchar frash_cnt;
extern uchar wei_buf;
void calc_sm(float value);
void display();
void delay(uint i);
#endif
定時器配置及中斷服務函數
#include "reg52.h"
#include "timer.h"
#include "shumaguan.h"
float xdata value=0 , value_now = 0;
void timer_init()
{
TMOD = 0x02; //set timer0 as mode1 (16-bit)
TL0 = T1MS; //initial timer0 low byte
TH0 = T1MS; //initial timer0 high byte
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch
}
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
if(value!=value_now)//檢測顯示值與當前值是否匹配
{
value=value_now;//刷新顯示值
calc_sm(value_now);//重新計算顯示值的輸出緩沖區
}
display();//刷新數碼管顯示
}
定時器頭文件
#ifndef _timer_h_
#define _timer_h_
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
//-----------------------------------------------
/* define constants */
//#define FOSC 11059200L
#define FOSC 12000000L
#define T1MS 0 //1ms timer calculation method in 12T mode
//-----------------------------------------------
extern float xdata value , value_now;
void timer_init();
#endif
上一篇:單片機控制LCD1602顯示英文句子
下一篇:基于單片機的電子琴設計和硬件平臺設計
推薦閱讀
史海拾趣
GPD Optoelectronics Corp公司發展故事
故事一:初創與鍺晶體管的誕生
GPD Optoelectronics Corp.(前身為Germanium Power Devices Corp.)成立于1973年,最初專注于高品質鍺晶體管的制造。在那個半導體技術剛剛起步的年代,鍺晶體管作為重要的電子元件,在電子行業中占據著舉足輕重的地位。公司憑借其精湛的工藝和嚴格的質量控制,迅速在市場中站穩了腳跟,為后續的光電二極管業務打下了堅實的基礎。
故事二:轉型為光電二極管制造商
進入1980年代,隨著光電技術的快速發展,GPD Optoelectronics Corp.敏銳地捕捉到了市場趨勢,開始逐步轉型為光電二極管制造商。1980年,公司成功推出了Ge pn探測器產品,標志著其正式進入光電領域。這一轉型不僅拓寬了公司的業務范圍,也為其后續在光電領域的深入發展奠定了技術基礎。
故事三:InGaAs探測器的研發與推廣
為了進一步滿足市場對高性能光電探測器的需求,GPD Optoelectronics Corp.在1993年推出了InGaAs探測器產品。InGaAs探測器以其優異的光譜響應范圍和靈敏度,在光通信、光譜學等領域得到了廣泛應用。公司的這一舉措不僅鞏固了其在光電領域的領先地位,也為其贏得了更多客戶的青睞。
故事四:產能擴大與技術創新
進入21世紀,GPD Optoelectronics Corp.繼續保持著強勁的發展勢頭。2000年,公司搬遷至新罕布什爾州塞勒姆的新工廠,產能實現了翻倍增長。同時,公司不斷加大研發投入,推出了多款創新產品,如擴展波長InGaAs探測器、可定制的雙色探測器以及InGaAs象限光電二極管等。這些產品的推出不僅豐富了公司的產品線,也進一步提升了其市場競爭力。
故事五:表面貼裝封裝選項的引入
隨著電子產品的不斷小型化和集成化,GPD Optoelectronics Corp.緊跟市場趨勢,于2019年增加了表面貼裝封裝選項。這一舉措使得公司的光電二極管產品更加符合現代電子產品的設計要求,進一步拓寬了其在智能手機、平板電腦等消費電子領域的應用市場。同時,公司也繼續致力于為客戶提供量身定制的定制零件服務,以滿足不同客戶的特定需求。
隨著計算機技術的飛速發展,處理器成為了電子設備的核心部件。Cicoil公司看到了這一趨勢,開始與處理器制造商展開合作。他們為處理器提供高質量的連接電纜,確保處理器能夠穩定、高效地運行。這一合作使得Cicoil公司的電纜產品進一步深入到計算機領域,也為其帶來了更多的商業機會。
隨著產品技術的成熟,長園維安開始積極拓展國際市場。公司與國際知名企業建立合作關系,共同開發新產品,拓展市場份額。同時,長園維安還積極參加國際展覽,展示公司最新技術和產品,提高品牌知名度。這些努力使長園維安在全球電子行業中的影響力不斷增強。
在過去的六年里,ABLIC實現了高盈利,這得益于其不斷創新的產品線和市場策略。為了進一步拓展業務,ABLIC將目光投向了歐洲市場。歐洲作為全球電子產業的重要區域,對于模擬半導體的需求持續增長。ABLIC憑借其在小型、低功耗和精確模擬半導體產品方面的優勢,積極在歐洲市場尋求合作機會,為公司的長遠發展奠定了堅實基礎。
在“2018慕尼黑上海電子展”上,ABLIC展示了其即將推出的紫外傳感器。這一產品的推出,彰顯了ABLIC在傳感器領域的創新能力。紫外傳感器在環境監測、安全防護等領域具有廣泛應用前景。ABLIC憑借其在半導體技術方面的深厚積累,成功研發出具有高性能和穩定性的紫外傳感器,為市場帶來了新的選擇。
Bias Power公司深知研發實力是企業發展的核心。因此,公司投入大量資源用于研發工作,建立了完善的研發團隊和實驗設施。通過不斷的技術創新和研發投入,Bias Power公司成功推出了一系列具有競爭力的新產品,鞏固了其在電子行業的領先地位。
同時,公司還注重知識產權的保護,積極申請專利,保護其核心技術不被侵犯。這些專利的申請和授權不僅提升了公司的技術實力,還為公司的發展提供了有力保障。
檢測前要了解集成電路及其相關電路的工作原理。 檢查和修理集成電路前首先要熟悉所用集成電路的功能、內部電路、主要電氣參數、各引腳的作用以及引腳的正常電壓、波形與外圍元件組成電路的工作原理。如果具備以上條件,那么分析和檢查會容易許多。 ...… 查看全部問答∨ |
三星的2416驅動7寸屏AT070TN84的問題!!!!急!!!! 處理器是s3c2416 ,BSP是2450的(據說這兩個處理器類似), LCD是 7寸TFT屏AT070TN84!!!! 現在的現象是,我在OEMINIT中初始化LCD,并讓其顯示藍色,然后進入CE系統,但是,該顯示藍色的時候LCD顯示的就象屏被關掉沒上電一樣(類似 ...… 查看全部問答∨ |
有的筆記本按下顯示切換熱鍵能切換到LCD+CRT extended模式,是怎樣實現的?? 有的筆記本按下顯示切換熱鍵能切換到LCD+CRT extended模式,是怎樣實現的?? 一般的顯示切換只會在LCD, CRT, LCD+CRT Clone三種模式下進行切換,但是有的notebook能切換到LCD+CRT extended模式,有誰知道這是怎樣實現的?是bios還是driver或者softw ...… 查看全部問答∨ |
我利用FindFirstFile和FindNextFile 系統中已存在的文件,代碼如下: CString cFileList[50]; int nFileTotalCount; nFileTotalCount=0; &nb ...… 查看全部問答∨ |
程序運行到sprintf時死機了,調式后發現進入了HardFault_Handler里死循環了。請問這個問題可能由啥原因引起的?還有貌似選了優化后,有時sprintf出來的數據會有錯誤?這個可能由啥原因引起的?謝謝!… 查看全部問答∨ |
不知道LM3S6911 的JTAG口能否接5V上拉?? 有客戶之前上拉到5V能正常燒錄,lay的板是上拉5V的,現在只能拉到3.3V才能工作。 求解!… 查看全部問答∨ |
本帖最后由 dontium 于 2015-1-23 13:09 編輯 TI旋轉電機:憑借自身在高級電機驅動和控制領域的深厚歷史積淀與門類寬泛的模擬和微控制器產品庫,TI可提供完整的電機系統解決方案,從而成為全球市場的領先者。TI將其在電機驅動和控制領域的豐富經驗 ...… 查看全部問答∨ |
|
void NVIC_Configuration_TIM5(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;   ...… 查看全部問答∨ |
也有很多對于使用TF卡的場合,功耗還是要講究的 那么不使用時功耗多大?讀或者寫的時候功耗又是多大?有做過實驗的么? 不同品牌的TF做過比較么? 不同的初始化方式例如使用SPI方式功耗又怎樣呢?… 查看全部問答∨ |