RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

應(yīng)廣單片機(jī)系列——基本應(yīng)用程序框架

聚豐開(kāi)發(fā) ? 2018-10-18 12:49 ? 次閱讀

注:本文是作者以前發(fā)表在其個(gè)人博客,現(xiàn)在發(fā)布到電子發(fā)燒友專(zhuān)欄


單片機(jī)工程師面對(duì)一種新單片機(jī)時(shí),最希望的是能有一個(gè)簡(jiǎn)單的樣例,這個(gè)樣例連上仿真器就能運(yùn)行,里面最好包含一些基本功能,這樣工程師就可以在這個(gè)樣例的基礎(chǔ)上很快改出自己需要的代碼。

這里我以應(yīng)廣pdk22c12寫(xiě)了一段程序框架,已經(jīng)包含對(duì)這個(gè)單片機(jī)的各種基本設(shè)置,拿回去就可以自己進(jìn)行仿真調(diào)試,相信能讓新接觸應(yīng)廣單片機(jī)的朋友很快上手。

//-----------------------------------------
//應(yīng)廣單片機(jī)軟件基本框架例程
//本例僅供參考,歡迎指正程序中的問(wèn)題
//本例是根據(jù)應(yīng)廣單片機(jī)的特點(diǎn)創(chuàng)建的基本程序框架
//包含定時(shí)中斷、外部中斷、AD轉(zhuǎn)換、段位數(shù)碼管顯示,簡(jiǎn)單按鍵處理等功能
//用戶(hù)在本例基礎(chǔ)上很容易就能改出自己需要的程序

.chippdk22c12
//{{PADAUK_CODE_OPTION
.Code_OptionLVD2.4V~2.9V// Maximum performance = 8 MIPS
.Code_OptionSecurityEnable// Security 7/8 words Enable
//}}PADAUK_CODE_OPTION
//#define MOB_FLASH_MODE

KEYequpa.5

//定義數(shù)碼管的IO口,這里是顯示三個(gè)8
LED_Aequpa.1
LED_Bequpa.0
LED_Cequpa.7
LED_Dequpa.6
LED_Eequpb.7
LED_Fequpb.6
LED_Gequpb.5
LED_DPequpb.1
LED_COM1equpa.2
LED_COM2equpa.3
LED_COM3equpa.4
LED_A_ONequset1LED_A
LED_A_OFFequset0LED_A
LED_B_ONequset1LED_B
LED_B_OFFequset0LED_B
LED_C_ONequset1LED_C
LED_C_OFFequset0LED_C
LED_D_ONequset1LED_D
LED_D_OFFequset0LED_D
LED_E_ONequset1LED_E
LED_E_OFFequset0LED_E
LED_F_ONequset1LED_F
LED_F_OFFequset0LED_F
LED_G_ONequset1LED_G
LED_G_OFFequset0LED_G
LED_DP_ONequset1LED_DP
LED_DP_OFFequset0LED_DP
SELECT_LED1macro
set1LED_COM2
set1LED_COM3
set0LED_COM1
endm
SELECT_LED2macro
set1LED_COM1
set1LED_COM3
set0LED_COM2
endm
SELECT_LED3macro
set1LED_COM1
set1LED_COM2
set0LED_COM3
endm
ALL_LED_OFFmacro
set1LED_COM1
set1LED_COM2
set1LED_COM3
LED_A_OFF
LED_B_OFF
LED_C_OFF
LED_D_OFF
LED_E_OFF
LED_F_OFF
LED_G_OFF
LED_DP_OFF
endm

LED_DELAYmacro
delay250
delay250
endm

wordinit_timer
//用于數(shù)碼管顯示時(shí)進(jìn)行查表轉(zhuǎn)換
worddisp_ptr
worddisp_data
worddisp_data_temp

byteXms
bytems_cnt
bytepb2_voltage

//用于數(shù)碼管顯示
bytedisp1_buf
bytedisp2_buf
bytedisp3_buf
bytedisp_temp
byteled1_buf
byteled2_buf
byteled3_buf

//用于定時(shí)中斷計(jì)時(shí)
bytetimer_cnt
//用于單鍵按鍵判斷
bytekey_cnt
bitkey_press_flag

//定義標(biāo)志位,用于數(shù)碼管顯示和閃爍控制
bitled_en_flag
bitled_flash_flag
bitupdate_disp_flag

//應(yīng)廣單片機(jī)程序入口,第一條必須為跳轉(zhuǎn)到第一個(gè)內(nèi)核主程序入口地址的指令,第二條為第二個(gè)內(nèi)核,有幾個(gè)內(nèi)核就有幾條
.romadr 0x000
gotomain0
gotomain1


//應(yīng)廣單片機(jī)中斷程序入口地址,所有中斷共用同一個(gè)入口,需要用戶(hù)自己判斷中斷類(lèi)型
.romadr 0x010
pushaf
if(intrq.T16)//定時(shí)中斷
{
stt16init_timer//重設(shè)定時(shí)器
if(timer_cnt < 9)?//得到1000ms間隔
{
timer_cnt ++
}
else
{
timer_cnt = 0
if(led_flash_flag)//數(shù)碼管閃爍處理
{
led_flash_flag = 0
}
else
{
led_flash_flag = 1
}
}
intrq.T16 = 0
}
elseif(intrq.PB0)//PB0外部中斷
{
if(pb.0)
{
//讀到PB0狀態(tài)為高,為上升沿
nop//添加用戶(hù)自己的代碼
}
else
{
//讀到PB0狀態(tài)為低,為下降沿
nop//添加用戶(hù)自己的代碼
}
}
intrq.AD = 0//強(qiáng)制清除AD中斷標(biāo)志位,防止意外進(jìn)入AD中斷后程序不停響應(yīng)
intrq.PA0 = 0//強(qiáng)制清除PA0外部中斷標(biāo)志位,防止意外進(jìn)入PA0中斷后程序不停響應(yīng)
popaf
reti

//----------------------------------------
//input: ms
//用該函數(shù)可以再4M的頻率下得到近似1毫秒的延時(shí),在第一個(gè)內(nèi)核中調(diào)用中斷會(huì)導(dǎo)致延時(shí)加長(zhǎng)
//----------------------------------------
delayXms:
while(Xms)
{
wdreset//這里需要有清看門(mén)狗操作,否則有可能在長(zhǎng)延時(shí)下導(dǎo)致看門(mén)狗溢出復(fù)位
ms_cnt = 20
while(ms_cnt)
{
delay195
ms_cnt--
}
Xms--
}
ret


//----------------------------------------
//
//對(duì)PB2進(jìn)行AD轉(zhuǎn)換,得到上面的電壓
//----------------------------------------
get_pb2_voltage:
//對(duì)新的一路AD通道進(jìn)行AD轉(zhuǎn)換時(shí),第一次轉(zhuǎn)換的結(jié)果可能不可靠,這里連續(xù)轉(zhuǎn)換兩次,取第二次結(jié)果
//如果連續(xù)對(duì)同一通道進(jìn)行AD轉(zhuǎn)換,可以只轉(zhuǎn)換一次
adcc = 0b10_0010_00//enable ADC, select pb2
ad_start = 1
wait1ad_start//等待AD轉(zhuǎn)換結(jié)束
a = adcr//放棄第一次轉(zhuǎn)換結(jié)果
ad_start = 1
wait1ad_start
pb2_voltage = adcr//存儲(chǔ)第二次轉(zhuǎn)換結(jié)果
ret

//數(shù)碼管BCD顯示用的轉(zhuǎn)換表,最后的兩個(gè)0x00可以不要
//數(shù)碼管的a,b,...,g,dp分別對(duì)應(yīng)bit7,bit6,...,bit0
bcd_tbl://0~9
dc0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00,0x00
//----------------------------------------
//以十進(jìn)制形式顯示數(shù)據(jù)disp_data
//只修改顯示緩沖區(qū)
//----------------------------------------
update_led_disp_buf:
//a,b,...,g,dp --> bit7,bit6,...,bit0
if(!update_disp_flag)
{
disp_data_temp = disp_data//先將需要顯示的數(shù)據(jù)放到臨時(shí)中間變量中,防止轉(zhuǎn)換時(shí)數(shù)據(jù)更新導(dǎo)致顯示出錯(cuò)

//得到數(shù)據(jù)管第一位LED1的BCD碼
disp_temp = 0
while(disp_data_temp >= 100)//直接用循環(huán)減實(shí)現(xiàn)除法
{
disp_data_temp = disp_data_temp - 100
disp_temp ++
}
disp_ptr = bcd_tbl//查表操作
disp_ptr = disp_ptr + disp_temp
ldtabldisp_ptr
movdisp1_buf,a
//得到數(shù)據(jù)管第二位LED2的BCD碼
disp_temp = 0
while(disp_data_temp >= 10)
{
disp_data_temp = disp_data_temp - 10
disp_temp ++
}
disp_ptr = bcd_tbl
disp_ptr = disp_ptr + disp_temp
ldtabldisp_ptr
movdisp2_buf,a
//得到數(shù)據(jù)管第三位LED3的BCD碼
disp_temp = disp_data_temp
disp_ptr = bcd_tbl
disp_ptr = disp_ptr + disp_temp
ldtabldisp_ptr
movdisp3_buf,a

update_disp_flag = 1
}

ret

//第一個(gè)內(nèi)核程序入口
//----------------FPPA0-------------------
main0:

.ADJUST_OTP_IHRCR8MIPS// IHRC/2 = 8MIPS, WatchDog Disable, RAM 0,1 temporary be used

sp = 0x30//設(shè)置第一個(gè)內(nèi)核的堆棧地址

//禁止中斷和定時(shí)器
disgint
inten = 0
mova,0b000_11_111//disable timer
movt16m,a

//小延時(shí)后在修改其它系統(tǒng)狀態(tài)設(shè)置
delay200
clkmd.1 = 1//打開(kāi)看門(mén)狗,這個(gè)設(shè)置盡量靠前,以增強(qiáng)可靠性
wdreset//清看門(mén)狗

//設(shè)置IO口
pac = 0b1101_1111//PA5設(shè)置 IN
paph = 0b0000_0000
pbc = 0b1111_1010//PB2設(shè)為模擬輸入不開(kāi)上拉電阻,PB0設(shè)為輸入
pbph = 0b0000_0000//poll high

ALL_LED_OFF

init_timer = 7768//從7768進(jìn)行校準(zhǔn)為100ms
mova,0b100_11_111
movt16m,a
stt16init_timer

//上電后清需要使用的變量
key_cnt = 0
disp1_buf = 0
disp2_buf = 0
disp3_buf = 0
led1_buf = 0
led2_buf = 0
led3_buf = 0
update_disp_flag = 0
timer_cnt = 0
disp_data = 000
led_en_flag = 1 //數(shù)碼管進(jìn)行顯示

//將PB2設(shè)為模擬輸入口進(jìn)行AD轉(zhuǎn)換
adcdi = 0b0000_0100//pb2 is analog input
adcc = 0b10_0010_00//enable ADC, select pb2
adcm = 0b000_0100_0//system clock/16
//adcm = 0b000_0111_0//system clock/128

//延時(shí)一段時(shí)間等系統(tǒng)穩(wěn)定
Xms = 100
calldelayXms

//得到按鍵初始狀態(tài),這樣在按鍵損壞時(shí)不會(huì)誤判按鍵按下或松開(kāi)
if(!KEY)
{
key_press_flag = 1
}
else
{
key_press_flag = 0
}


stt16init_timer
intrq = 0
inten.T16 = 1//打開(kāi)定時(shí)中斷
inten.PB0 = 1//打開(kāi)PB0外部中斷
engint//允許中斷
set1fppen.1//打開(kāi)第二個(gè)內(nèi)核

main0_loop:

wdreset//clear watch dog

//得到PB2的AD轉(zhuǎn)換結(jié)果
callget_pb2_voltage
//AD轉(zhuǎn)換完立即更新數(shù)碼管顯示緩沖區(qū)
callupdate_led_disp_buf

if(!KEY)//電壓恢復(fù)正常只要按鍵就立刻結(jié)束倒計(jì)時(shí)
{
if(key_cnt < 3)
{
key_cnt ++
}
else
{
if(!key_press_flag)
{
key_press_flag = 1//這里是按鍵按下
//按鍵切換數(shù)碼管是否進(jìn)行顯示
if(led_en_flag)
{
led_en_flag = 0//數(shù)碼管不顯示
}
else
{
led_en_flag = 1//數(shù)碼管顯示
}
}
}
}
else
{
if(key_cnt)
{
key_cnt --
}
else
{
if(key_press_flag)
{
key_press_flag = 0//這里是按鍵松開(kāi)
}
}
}

//延時(shí)50毫秒,目的是讓第一個(gè)內(nèi)核循環(huán)的時(shí)間大于第二個(gè)內(nèi)核循環(huán)時(shí)間的兩倍
//以保證顯示緩沖區(qū)再次更新前第二個(gè)核已經(jīng)做出響應(yīng),保證顯示正確
Xms = 50
calldelayXms

gotomain0_loop

//第二個(gè)內(nèi)核程序入口
//----------------FPPA1-------------------
main1:
sp = 0x38//設(shè)置第二個(gè)內(nèi)核的堆棧地址
delay200
main1_loop:
if(update_disp_flag)//有數(shù)據(jù)更新時(shí)才進(jìn)行更新
{
led1_buf = disp1_buf
led2_buf = disp2_buf
led3_buf = disp3_buf
update_disp_flag = 0
}

//第二個(gè)內(nèi)核循環(huán)掃描顯示數(shù)碼管,這樣可以得到?jīng)]有閃爍的顯示效果
if(led_en_flag)//數(shù)碼管需要顯示
{
//下面程序盡量讓數(shù)碼管每個(gè)段位的處理時(shí)間相同,這樣可以保證各個(gè)段位亮度一致
//LED1
ALL_LED_OFF
LED_DELAY
SELECT_LED1
if(led1_buf.7)
{
LED_A_ON
}
LED_DELAY
LED_A_OFF
if(led1_buf.6)
{
LED_B_ON
}
LED_DELAY
LED_B_OFF
if(led1_buf.5)
{
LED_C_ON
}
LED_DELAY
LED_C_OFF
if(led1_buf.4)
{
LED_D_ON
}
LED_DELAY
LED_D_OFF
if(led1_buf.3)
{
LED_E_ON
}
LED_DELAY
LED_E_OFF
if(led1_buf.2)
{
LED_F_ON
}
LED_DELAY
LED_F_OFF
if(led1_buf.1)
{
LED_G_ON
}
LED_DELAY
LED_G_OFF
if(led1_buf.0)
{
LED_DP_ON
}
LED_DELAY
LED_DP_OFF
//LED2
ALL_LED_OFF
LED_DELAY
SELECT_LED2
if(led2_buf.7)
{
LED_A_ON
}
LED_DELAY
LED_A_OFF
if(led2_buf.6)
{
LED_B_ON
}
LED_DELAY
LED_B_OFF
if(led2_buf.5)
{
LED_C_ON
}
LED_DELAY
LED_C_OFF
if(led2_buf.4)
{
LED_D_ON
}
LED_DELAY
LED_D_OFF
if(led2_buf.3)
{
LED_E_ON
}
LED_DELAY
LED_E_OFF
if(led2_buf.2)
{
LED_F_ON
}
LED_DELAY
LED_F_OFF
if(led2_buf.1)
{
LED_G_ON
}
LED_DELAY
LED_G_OFF
if(led2_buf.0)
{
LED_DP_ON
}
LED_DELAY
LED_DP_OFF
//LED3
ALL_LED_OFF
LED_DELAY
SELECT_LED3
if(led3_buf.7)
{
LED_A_ON
}
LED_DELAY
LED_A_OFF
if(led3_buf.6)
{
LED_B_ON
}
LED_DELAY
LED_B_OFF
if(led3_buf.5)
{
LED_C_ON
}
LED_DELAY
LED_C_OFF
if(led3_buf.4)
{
LED_D_ON
}
LED_DELAY
LED_D_OFF
if(led3_buf.3)
{
LED_E_ON
}
LED_DELAY
LED_E_OFF
if(led3_buf.2)
{
LED_F_ON
}
LED_DELAY
LED_F_OFF
if(led3_buf.1)
{
LED_G_ON
}
LED_DELAY
LED_G_OFF
if(led3_buf.0)
{
LED_DP_ON
}
LED_DELAY
LED_DP_OFF
}
else//數(shù)碼管不需要顯示
{
ALL_LED_OFF
}

gotomain1_loop

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6035

    文章

    44554

    瀏覽量

    634634
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    單片機(jī)Debug工具性能對(duì)比 單片機(jī)調(diào)試常用命令

    單片機(jī)(Microcontroller Unit, MCU)調(diào)試是嵌入式開(kāi)發(fā)中的一個(gè)重要環(huán)節(jié),它幫助開(kāi)發(fā)者發(fā)現(xiàn)和修復(fù)代碼中的錯(cuò)誤,優(yōu)化程序性能。不同的單片機(jī)和開(kāi)發(fā)環(huán)境可能使用不同的調(diào)試工具和命令
    的頭像 發(fā)表于 12-19 09:56 ?124次閱讀

    單片機(jī)怎么寫(xiě)入程序

    程序通常涉及以下幾個(gè)步驟: 選擇單片機(jī)和開(kāi)發(fā)環(huán)境 : 確定項(xiàng)目需求,選擇合適的單片機(jī)型號(hào)。 安裝相應(yīng)的開(kāi)發(fā)環(huán)境,如Keil、IAR、MPLAB等。 硬件連接 : 將單片機(jī)連接到開(kāi)發(fā)板或
    的頭像 發(fā)表于 10-21 11:21 ?426次閱讀

    單片機(jī)的中斷機(jī)制

    單片機(jī)的中斷機(jī)制是一種重要的處理方式,它允許單片機(jī)在執(zhí)行主程序的過(guò)程中,能夠暫停當(dāng)前任務(wù),轉(zhuǎn)而處理外部或內(nèi)部緊急事件。這種機(jī)制極大地提高了系統(tǒng)的響應(yīng)速度和處理能力,使得單片機(jī)在各種應(yīng)用
    的頭像 發(fā)表于 10-17 18:03 ?619次閱讀

    通過(guò)DaVinci TMS320DM644x的串行接口加載基本應(yīng)用程序

    電子發(fā)燒友網(wǎng)站提供《通過(guò)DaVinci TMS320DM644x的串行接口加載基本應(yīng)用程序.pdf》資料免費(fèi)下載
    發(fā)表于 10-16 11:52 ?0次下載
    通過(guò)DaVinci TMS320DM644x的串行接口加載基<b class='flag-5'>本應(yīng)用程序</b>

    keil可以讀出單片機(jī)程序

    Keil是一款廣泛應(yīng)用于單片機(jī)程序開(kāi)發(fā)的軟件,它提供了包括C編譯器、宏匯編、連接器、庫(kù)管理和一個(gè)功能強(qiáng)大的仿真調(diào)試器等在內(nèi)的完整開(kāi)發(fā)方案。然而,關(guān)于Keil是否能直接“讀出”單片機(jī)程序
    的頭像 發(fā)表于 09-02 10:32 ?911次閱讀

    單片機(jī)燒錄程序用什么軟件

    單片機(jī)燒錄程序單片機(jī)開(kāi)發(fā)過(guò)程中的一個(gè)重要環(huán)節(jié),涉及到將編寫(xiě)好的程序代碼通過(guò)燒錄器寫(xiě)入單片機(jī)的ROM中,以實(shí)現(xiàn)對(duì)
    的頭像 發(fā)表于 09-02 10:05 ?1151次閱讀

    單片機(jī)燒錄程序可以重新燒嗎

    單片機(jī)(Microcontroller Unit, MCU)是一種集成電路芯片,它將計(jì)算機(jī)的CPU、存儲(chǔ)器、輸入/輸出接口等集成在一塊芯片上,用于控制各種電子設(shè)備。單片機(jī)燒錄程序是指將編寫(xiě)
    的頭像 發(fā)表于 09-02 10:04 ?1174次閱讀

    單片機(jī)燒錄程序的線(xiàn)比單片機(jī)上的少還能燒錄嗎

    單片機(jī)燒錄原理 單片機(jī)燒錄是指將編寫(xiě)好的程序代碼通過(guò)一定的方式傳輸?shù)?b class='flag-5'>單片機(jī)的存儲(chǔ)器中,使其能夠按照程序的指令運(yùn)行。這個(gè)過(guò)程通常需要使用燒錄器
    的頭像 發(fā)表于 09-02 09:54 ?480次閱讀

    單片機(jī)燒錄程序的基本步驟是什么

    單片機(jī)燒錄程序的基礎(chǔ),它包含了單片機(jī)芯片、電源、接口等基本元件。在選擇單片機(jī)開(kāi)發(fā)板時(shí),需要考慮以下幾個(gè)方面: (1)單片機(jī)型號(hào):根據(jù)項(xiàng)目需
    的頭像 發(fā)表于 09-02 09:47 ?995次閱讀

    stm32單片機(jī)燒錄程序會(huì)擦除原來(lái)的程序

    在STM32單片機(jī)燒錄程序的過(guò)程中, 通常情況下會(huì)擦除原來(lái)的程序 ,并將新程序寫(xiě)入單片機(jī)的閃存(Flash)中。這一過(guò)程是通過(guò)燒錄工具(如S
    的頭像 發(fā)表于 09-02 09:42 ?1905次閱讀

    單片機(jī)中斷功能及其應(yīng)用

    單片機(jī)中斷功能及其應(yīng)用? 單片機(jī)中斷是指在程序執(zhí)行過(guò)程中,根據(jù)特定的條件或事件自動(dòng)暫時(shí)中斷當(dāng)前程序的執(zhí)行,轉(zhuǎn)而執(zhí)行特定的中斷服務(wù)程序。中斷是
    的頭像 發(fā)表于 01-30 14:45 ?5259次閱讀

    單片機(jī)應(yīng)科技的一款8位MTP型單片機(jī)PFS123介紹

    應(yīng)PFS123單片機(jī)片概述 PFS123 是一款基于 CMOS 帶 8位 ADC 的 MTP 的8 位微控制器。它運(yùn)用 RISC 的架構(gòu)基礎(chǔ)使大部分的指令執(zhí)行時(shí)間都是一個(gè)指令周期,只有少部分
    的頭像 發(fā)表于 01-17 11:31 ?1463次閱讀

    單片機(jī)芯片怎么寫(xiě)入程序

    單片機(jī)工作,我們需要向其非易失性存儲(chǔ)器中寫(xiě)入程序。本文將介紹單片機(jī)芯片程序寫(xiě)入的過(guò)程和方法。 單片機(jī)芯片
    的頭像 發(fā)表于 01-05 14:06 ?8271次閱讀

    單片機(jī)程序讀取需要什么工具

    單片機(jī)程序讀取的工具可以分為硬件工具和軟件工具兩類(lèi)。下面將詳細(xì)介紹這些工具的種類(lèi)、功能和使用方法。 一、硬件工具 單片機(jī)開(kāi)發(fā)板:單片機(jī)開(kāi)發(fā)板是最基本的硬件工具之一,它通常由主控芯片、輸
    的頭像 發(fā)表于 01-02 18:10 ?3818次閱讀

    keil5mdk怎么編寫(xiě)51單片機(jī)程序

    編寫(xiě)51單片機(jī)程序需要以下步驟: 編寫(xiě)程序框架:首先,你需要定義程序所需要的變量和常量,以及設(shè)置中斷向量和寄存器的初始狀態(tài)。這些信息可以根據(jù)
    的頭像 發(fā)表于 12-25 14:54 ?1542次閱讀
    RM新时代网站-首页