實驗三 一、實驗目的 (1) 了解模擬量采樣的硬件電路;
(2) 熟悉 AD 的結構,掌握 AD 寄存器的使用方法;
(3) 掌握正確配置引腳的方法,實現指定功能;
(4) 熟悉串口的機制,掌握串口寄存器的使用方法;
(5) 實現模擬量采樣,并將采樣結果通過串口上傳至 PC 端。 二、實驗內容 (1) 運行AD 示例程序, 正確配置 PA0 引腳,實現 AD 采樣功能;
(2) 運行 UART3 示例程序, 正確配置串口 3, 實現數據通過串口上傳 PC;
(3) 按照實驗要求編寫應用程序。 三、實驗中所用到的主要外設及其寄存器的簡要說明 (1)ADC模數轉換模塊: 用來采集PA0口的電壓值,并將其轉換為數字量(0~4095)存放在ADC的DR寄存器中。 (2)DMA直接內存訪問模塊: 用來將ADC的DR寄存器中的值拷貝到內存中。 (3)四位數碼管模塊: 用來顯示ADC采集到的電壓值。接GPIOE.PIN[0:11]。其中GPIO.PIN[0:7]為段選端,分別對應某一位數碼管的a-f, dp 段。DPIO.PIN[8:11]為位選端,分別對應從左至右第1-4位數碼管。 (4)USART3串口模塊: 用來將ADC采集到的電壓值通過USART3發送給電腦。通過軟件將電壓值轉換為四位字符數組,然后按字符放入USART3的DR寄存器中。等待硬件控制自動發送。等到USART3的SR寄存器的TC位置位后把下一位字符放入DR寄存器。直到四位字符全部發送完成。 (5)定時器TIM3: 用來為數碼管計時,溢出周期是1ms。當計時器溢出時觸發中斷,點亮相應位的數碼管,顯示數字是步數的相應位。 (6)定時器TIM2: 用來為ADC采樣計時,溢出周期時500ms。當計時器溢出時觸發中斷,開始一次ADC采樣。 四、程序框圖
五、核心程序 (1)main.c #include "stm32f10x.h" #include "adc.h" #include "dma.h" #include "nixie_tubes.h" #include "tim.h" #include "usart.h" #include "led.h" #include "stdio.h"
#define ADC_DATA_LEN 1
USART_Data data;
int main() { data.flag = 1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Adc1_Init(); Dma_Init((u32) &(ADC1->DR), (u32) &(data.dint), ADC_DATA_LEN); USART3_Init(115200); USART_NVIC_init(); Tim2_DelayMs_Init(500);
NixieTube_Init(); Tim3_Display_Init();
TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM3, ENABLE);
while(1) { while(data.flag == 0); //Wait until data flag was set sprintf(data.dchar, "%4d", data.dint); //Transform the type of data from int into 4 characters Usart_send_datas(data.dchar); //Send data.dchar to USART3 data.flag = 0; //Reset data flag }
} (2)tim.c //定時器2中斷服務程序 void TIM2_IRQHandler(void) //TIM2中斷 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //檢查TIM2更新中斷發生與否 { TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx更新中斷標志 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能 //MyDMA_Start_Once(); data.flag = 1; } }
//TIM3 for delay void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查TIM2更新中斷發生與否 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); if(data_bit == 0) data_bit = 4;
switch(data_bit) { case 1: {Nixietube_light(1, data.dchar[0]);break;} case 2: {Nixietube_light(2, data.dchar[1]);break;} case 3: {Nixietube_light(3, data.dchar[2]);break;} case 4: {Nixietube_light(4, data.dchar[3]);break;}
default: break; }
data_bit -= 1; }
} (3)usart.c u8 Usart_send_datas(u8* data) { u16 k = 0;
for(k=0; *(data + k) != '\0'; k++) { USART_SendData(USART3,*(data + k)); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); } USART_SendData(USART3, 0x0d); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); USART_SendData(USART3, 0x0a); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
return 0;
} |