|
本帖最后由 黃進盛 于 2018-5-11 21:17 編輯
關于新唐C51,N76E003此款芯片的定時器、ADC功能的使用備錄
使用方向:基于官方提供的Demo Code庫(N76E003_BSP_Keil_C51_V1.0.5)
使用意圖:使用N76E003的定時器功能,進行模擬時鐘設計,ADC采集(注:沒有使用時鐘IC,個人只是單純用來計時定時)
結果:功能已經實現。
個人項目經驗總結:
一、項目背景:基于新唐MCU (51)N76E003+LCM設計調試采集系統電壓電流情況,記錄相關項目過程經驗從而進行后面的系統設計。
二、項目模塊與功能使用結果:1、定時器模塊,2、ADC模塊,3、中斷模塊;LCM液晶顯示模塊;按鍵模塊。(備注:實現)
三、項目樣機圖片:
1.jpg (444.81 KB, 下載次數: 72)
下載附件
2018-5-11 20:56 上傳
四、項目程序開發記錄:
1、流程圖:這里就不提供了,想必只有我這種單片機使用(能力水平:半桶水,哈哈)才要個流程圖了。
2、單獨調試各個使用模塊:ADC模塊:以下是官方提供ADC的demo Code
ADC.png (10.43 KB, 下載次數: 74)
下載附件
2018-5-11 20:57 上傳
ADCcode.png (8.52 KB, 下載次數: 86)
下載附件
2018-5-11 20:58 上傳
官方提供了簡單能用的參考代碼,
以下是自己修改的多通道采集:
Uint32_t Get_ADC_Val(char channels)//獲取ADC通道ADC值
{
uint32_t ADC;
// CKDIV=0x02;
switch(channels)
{
case 4:
Enable_ADC_AIN4;
break;
case 5:
Enable_ADC_AIN5;
break;
case 6:
Enable_ADC_AIN6;
break;
case 7:
Enable_ADC_AIN7;
break;
}
clr_ADCF;
set_ADCS; // ADC start trig signal
while(ADCF == 0);
ADC=(ADCRH<<4)+ADCRL;
clr_ADCF;
// CKDIV=0x00;
return ADC;
}
小節總結:ADC的使用相信各位大神已經是使用的滾瓜爛熟了,我這種新手就不多提了,哈哈
附上一篇截圖官方文檔的ADC使用資料:
ADC data.png (197.45 KB, 下載次數: 74)
下載附件
2018-5-11 20:58 上傳
定時器模塊:官方庫中有各個定時器各個模式的sample Code附圖:
time.png (11.15 KB, 下載次數: 68)
下載附件
2018-5-11 21:00 上傳
簡單附上定時器0模式1(部分執行代碼)的官方代碼:
/************************************************************************************************************
* TIMER 1 interrupt subroutine
************************************************************************************************************/
void Timer1_ISR (void) interrupt 3 //interrupt address is 0x001B
{
TH1 = u8TH1_Tmp;
TL1 = u8TL1_Tmp;
P03 = ~P03; //P0.3 toggle when interrupt
}
/************************************************************************************************************
* Main function
************************************************************************************************************/
void main (void)
{
Set_All_GPIO_Quasi_Mode;
TIMER0_MODE1_ENABLE;
TIMER1_MODE1_ENABLE;
clr_T1M;
//set_T1M;
u8TH0_Tmp = (65536-TH0_INIT)/256;
u8TL0_Tmp = (65536-TL0_INIT)%256;
u8TH1_Tmp = (65536-TH1_INIT)/256;
u8TL1_Tmp = (65536-TL1_INIT)%256;
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
TH1 = u8TH1_Tmp;
TL1 = u8TL1_Tmp;
set_ET0; //enable Timer0 interrupt
set_ET1; //enable Timer1 interrupt
set_EA; //enable interrupts
set_TR0; //Timer0 run
set_TR1; //Timer1 run
while(1);
}
附上我自己(基于新唐官方庫)修改后的使用定時器執行代碼:
void Timer0_Init(void)//
{
//TMOD = 0XFF;
CKDIV=0X0C;
TIMER0_MODE1_ENABLE; //Timer 0 and Timer 1 mode configuration
// TIMER1_MODE2_ENABLE;
clr_T0M;
u8TH0_Tmp =TIMER_DIV12_VALUE_1ms>>8; //12分頻初值
u8TL0_Tmp =TIMER_DIV12_VALUE_1ms; //
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
set_ET0; //enable Timer0 interrupt
//set_ET1; //enable Timer1 interrupt
set_EA; //enable interrupts
set_TR0; //Timer0 run
//set_TR1; //Timer1 run
CKDIV=0X00;
}
void Timer0_ISR (void) interrupt 1
{
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
time_count++;
key_handle=1;
if(time_count==1000)
{
time_count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
}
}
}
TF0=0;
}
附上一張官方文檔:
tm1.png (75.09 KB, 下載次數: 69)
下載附件
2018-5-11 21:02 上傳
小節總結:官方提供的sample CODE 覆蓋了整個定時器模塊,給新人使用還是很有參考價值的,這次我也是第一次使用新唐的單片機,個人感覺還是挺方便的, N76E003 純C51風格開發,(但就是定時器的使用讓我思考起來人生),下載了官方庫下來參考,看工程,咦!代碼風格不一般,內設使用起來這么方便(庫都已近定義好了),這不是Ctrl+c\Ctrl+v就能解決了嗎!
這樣新手 用起來就難堪了,我怎么調試定時中斷時間都不對,難道是初值算錯了,于是又找度娘,看看定時器初值怎么計算。改了改溢出值(還是不對,能力不夠或者是解決問題的方向不對)于是又滑動鼠標滾輪看起了規格書(還好新唐的規格書是中文,不然就尷尬了)
規格書介紹的也挺簡單的呀,看了看又調試,還是不行。于是又回到了官方庫sample Code
附上一張官方庫的文件圖片:(提供的圖片沒什么用,就看看)
code.png (46.09 KB, 下載次數: 74)
下載附件
2018-5-11 21:03 上傳
在官方庫中的定時器模塊沒有找到解決方法。
哎,再仔細看看官方的庫
有這么一個源文件:
delay.png (100.83 KB, 下載次數: 61)
下載附件
2018-5-11 21:01 上傳
看到有以下這些像是定時器的延時代碼,想會不會是這些。
void Timer0_Delay100us(UINT32 u32CNT)
{
clr_T0M; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
set_TR0; //Start Timer0
while (u32CNT != 0)
{
TL0 = LOBYTE(TIMER_DIV12_VALUE_100us); //Find define in "Function_define.h" "TIMER VALUE"
TH0 = HIBYTE(TIMER_DIV12_VALUE_100us);
while (TF0 != 1); //Check Timer0 Time-Out Flag
clr_TF0;
u32CNT --;
}
clr_TR0; //Stop Timer0
}
//------------------------------------------------------------------------------
void Timer0_Delay1ms(UINT32 u32CNT)
{
clr_T0M; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
set_TR0; //Start Timer0
while (u32CNT != 0)
{
TL0 = LOBYTE(TIMER_DIV12_VALUE_1ms); //Find define in "Function_define.h" "TIMER VALUE"
TH0 = HIBYTE(TIMER_DIV12_VALUE_1ms);
while (TF0 != 1); //Check Timer0 Time-Out Flag
clr_TF0;
u32CNT --;
}
clr_TR0; //Stop Timer0
}
像延時一樣,填上定時器初值看看定時中斷對不對,調試又不對
TL0 = Timer0_Delay1ms(1);//1ms定時中斷 初值
TH0 = Timer0_Delay1ms(1);
不對,,,,,,,還是不對。
再找找看看怎么解決,(又回到了下面的文件里,定時器初值的定義),填上去試試對不對,還是不對,呀呀呀呀呀。
s.png (164.39 KB, 下載次數: 63)
下載附件
2018-5-11 21:05 上傳
仔細思考了一會,#define TIMER_DIV12_VALUE_1ms 65536-1334//1334*12/16000000 = 1 mS, // Timer divider = 12
這個初值是要對定時器模塊進行相關的分頻后的初值嗎?
于是又看起了官方庫,沒有相關的定時器分頻的使用參考呀,于是再回到了規格書:
找分頻的使用介紹看看:附上圖片:
sz.png (158.67 KB, 下載次數: 74)
下載附件
2018-5-11 21:06 上傳
sz1.png (100.91 KB, 下載次數: 75)
下載附件
2018-5-11 21:06 上傳
看到這些資料,試試對定時器進行時鐘分頻調調看:于是就又了以下代碼:
c2.png (18.65 KB, 下載次數: 71)
下載附件
2018-5-11 21:07 上傳
前面已經貼出,這里貼圖片只做經驗介紹總結。這里箭頭和圈圈的就是我的解決方法了,定時器1ms中斷實現了,時鐘終于跑正常了,(對定時器進行12分頻,才是正確附初值的正確方法)一天時間也就這樣給沒有了,這是新手的痛呀,時間寶貴。
注:以上圖片以及代碼只供個人經驗交流總結使用,請勿做其他用途使用;個人使用總結,還請各位多多指教交流 。
|
-
-
總結.docx
2018-5-11 21:10 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
958.13 KB, 下載次數: 64, 下載積分: 黑幣 -5
評分
-
查看全部評分
|