這是本人一個作業,卻整整花了兩天時間才搞完,因為網上關于stm32的仿真很少,所以應該是網上第一份protues兩塊單片機實作串口互動的程式,實在是值得紀念一下,
前文提要,由于protues仿真庫函式bug太多,所以采用暫存器的初始化版本原作者
后面會發原程式下載地址
首先我們知道串口互動程式需要uasrt初始化,這邊采用的是原子哥的例程實驗四的初始化,這個可以自行參考資料,這邊就不放代碼圖了,
led和key配置,這邊放兩個的.h代碼就好
//led.h
#define LED5 PBout(4)// PB4
#define LED4 PBout(5)// PB5
#define LED3 PBout(6)// PB6
void LED_Init(void);//初始化
//key.h
#define KEY0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)//讀取按鍵0
#define KEY1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)//讀取按鍵1
#define KEY2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)//讀取按鍵2
#define KEY3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)//讀取按鍵3
#define KEY4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)//讀取按鍵4
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY2按下
#define KEY3_PRES 4 //KEY3按下
#define KEY4_PRES 5 //KEY4按下
這兩個初始化程式也是原子哥的,可以自行找代碼參考如何實作,

這個是作業內容,但是問題是如何實作
按鍵控制實作比較簡單,如何實作發送信號和接收信號是一個問題
首先必須知道usar的函式是如何實作,這邊就介紹我們需要的發送和接收就好,
//USART_SenData
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
/* Transmit Data */
USARTx->DR = (Data & (uint16_t)0x01FF);
}
//例子
//USART_SendData(USART1, 0x00);
//發送0x02
0x02就是十六進制,0x02=00000010,這里我也不多贅述了,
這邊還有一個關鍵點,很多人可能發送資料只會發一個資料,例如:
USART_SendData(USART1,0x00) ;
USART_SendData(USART1,0x01) ;
USART_SendData(USART1,0x02) ; 這樣通過上位機收到的只是02并不是00 01 02
因為資料還來不及發送,資料就被后面來的資料覆寫了,所以收到的資料是02,不是00 01 02
USART_SendData(USART1,0x00) ;
delay_ms(1);
USART_SendData(USART1,0x01) ;
delay_ms(1);
USART_SendData(USART1,0x02) ;
delay_ms(1); 這樣收到的才是00 01 02
這個是個蠢辦法,但是由于本人也還沒理解那么多,就先用著,后面鏈接就是參考來源,里面有一個更好的設定辦法,
參考
然后是接收函式
USART_RX_BUF[0]==0x02;
//當第一個字符為0x02時
這個函式我也放個鏈接個需要的同學參考
STM32通過串口控制LED閃爍或者呼吸效果
這邊也有一個問題,由于protues仿真只能讀取第一一個字符,所以后面除錯程序我基本都是使用串口模擬器,讓計算機來除錯,
然后是主函式的東西,由于我寫的比較亂就放出一個給別人參考后面放源程式鏈接給同學,
int main(void)
{
vu8 key=0;
u8 t;
u8 len;
u16 times=0;
Stm32_Clock_Init(9); //系統時鐘設定
// delay_init(); //延時函式初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 設定中斷優先級分組2
uart_init(9600); //串口初始化為9600
LED_Init(); //初始化與LED連接的硬體介面
KEY_Init();
for(t=0;t<10;t++)
{
Array[t]=t;
}
while(1)
{
if(USART_RX_BUF[0]==0x01)
{
hxf_delay_s(10);
LED4=!LED4;
hxf_delay_s(10);
USART_SendData(USART1, 0x01);
hxf_delay_s(10);
USART_SendData(USART1, 0x01);
hxf_delay_s(10);
USART_SendData(USART1, 0x02);
hxf_delay_s(10);
USART_SendData(USART1, 0x03);
hxf_delay_s(10);
USART_SendData(USART1, 0xaa);
}
//輸如代碼和USART_RX_BUF
key=KEY_Scan(0); //得到鍵值
if(key)
{
switch(key)
{
case KEY2_PRES: //控制LED4點亮
delay_ms(1000);
LED4=!LED4;
hxf_delay_s(10);
USART_SendData(USART1, 0x01);
hxf_delay_s(10);
USART_SendData(USART1, 0x01);
hxf_delay_s(10);
USART_SendData(USART1, 0x02);
hxf_delay_s(10);
USART_SendData(USART1, 0x03);
hxf_delay_s(10);
USART_SendData(USART1, 0xaa);
}
break;
}
}
//key2 、led1和USART_SendData
這里面由于原本的時鐘不知道為什么定時不精確,也沒去深究,就自己按原本那個寫了一個新的放進main.c函式里面了,
這樣程式部分就完成了,
然后是仿真部分,先上一份仿真圖

這里面的stm32需要設定72MHZ,然后由于virtual teminal會吞掉信號,所以我們不使用他,后面看波形,我們在用示波器看,
用串口模擬器和xcom除錯看看運行如何,



發現符合要求,這邊仿真圖看看就行,因為protues的局限性太大了,這是我目前能做出來最完美的一份,然后兩塊單片機互動時候,大家可以自行用protues去嘗試,也是能成功的,希望對大家有用,
資源下載
QQ3209448656
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272952.html
標籤:其他
