用STM32F103RCT6的普通IO口模擬串列埠的實驗
阿新 • • 發佈:2019-02-02
使用了STM32CubeMX及Keil (HAL庫)
材料:stm32開發板、USB轉TTL?CH340模組、杜邦線、st-link
資料位:8
停止位:1
(1個數據10位)
無校驗位
用1個普通的GPIO口中斷輸入(模擬RXD),模擬了接收,下降沿觸發中斷,採用定時器延時,大概在資料位中央採集1次電平資料
實驗設計:
使用了PA1作TXD,PA2作RXD,然後連到CH340模組再連到電腦
TIM2延時
STM32CubeMX中的主要設定:
參考資料:普通的 http://www.eeworld.com.cn/mcu/article_2016053126671.html
材料:stm32開發板、USB轉TTL?CH340模組、杜邦線、st-link
實驗原理:
模擬了非同步半雙工通訊
波特率可變
起始位:1資料位:8
停止位:1
(1個數據10位)
無校驗位
傳輸一個字元的時候先發送1位起始位,然後是8位資料位(從低位到高位),最後是一位停止位
用1個普通的GPIO口輸出(模擬TXD),模擬了以上傳送的高低電平,採用定時器延時(一個位對應的電平的持續時間為1000000/波特率 μs)用1個普通的GPIO口中斷輸入(模擬RXD),模擬了接收,下降沿觸發中斷,採用定時器延時,大概在資料位中央採集1次電平資料
實驗設計:
使用了PA1作TXD,PA2作RXD,然後連到CH340模組再連到電腦
TIM2延時
實驗過程:
測試使用9600的波特率
一開始只實現了初始時傳送“hello”,以及環回測試的2位資料正確收發。。。
推斷PA1傳送功能應該成功了(然而經過邏輯分析儀檢測PA1傳送的一個位的延時達到106us左右,正常情況應該是104us),PA2接受功能有bug,一次只能正確接受2位資料,後面收到的都是錯誤的字元,推測是延時上時間誤差的問題,而且會自增像空格一樣的字元(經過邏輯分析儀的檢測其實是ascii碼為255的字元,多次測試發現應該是接受完所有字元後又觸發了中斷,然而後面都是高電平,所以就收到了這個字元)。。。
錯誤的結果:
然後根據推測改程式碼,把接收資料中的延時時間改小,忽略掉ascii碼為255的字元(簡單粗暴的方法。。。)
正確的結果:
STM32CubeMX中的主要設定:
主要程式碼(以下只有USER CODE BEGIN裡的程式碼):
/* USER CODE BEGIN Includes */
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ uint32_t baudrate=9600; //設定波特率,比如9600bps uint8_t message[20]; //收到的字元存放的字元陣列 uint8_t length=0; //收到的字元數 uint8_t welcome[]="hello"; //要傳送的一個初始資訊 uint32_t bit_time; /* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void delay_us(uint32_t counter);
void transmitChar(uint8_t ch);
uint8_t receiveChar(void);
void transmitString(uint8_t a[]);
/* USER CODE END PFP */
/* USER CODE BEGIN 1 */
bit_time=1000000/baudrate; //一個位的時間,單位us
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
transmitString(welcome); //傳送初始資訊
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
//延時counter(us)
void delay_us(uint32_t counter){
counter++;
HAL_TIM_Base_Start(&htim2);
__HAL_TIM_SET_COUNTER(&htim2,counter);
while(counter>1){
counter=__HAL_TIM_GET_COUNTER(&htim2);
}
HAL_TIM_Base_Stop(&htim2);
}
//傳送字元
void transmitChar(uint8_t ch){
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,(GPIO_PinState)0);
delay_us(bit_time);
uint8_t i,temp;
for(i=0;i<8;i++){
temp=ch&0x01;
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,(GPIO_PinState)temp);
delay_us(bit_time);
ch>>=1;
}
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,(GPIO_PinState)1);
delay_us(bit_time);
}
//傳送字串
void transmitString(uint8_t a[]){
uint8_t i,j;
j=strlen(a);
for(i=0;i<j;i++){
transmitChar(a[i]);
}
}
//接收字元
uint8_t receiveChar(void){
uint8_t bit,i,ch=0;
delay_us(bit_time*1.5);
for(i=0;i<8;i++){
bit=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2);
ch>>=1;
if(bit){
ch=ch|0x80;
}
delay_us(bit_time);
}
delay_us(bit_time*0.2);
return ch;
}
//GPIO的中斷回撥函式
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
uint8_t ch;
ch=receiveChar();
if(ch=='#'){
uint8_t i;
for(i=0;i<length;i++){
transmitChar(message[i]);
}
length=0;
}
else if(ch!=255){
message[length++]=ch;}
}
/* USER CODE END 4 */
實驗成果:
實現了19個字元以內的正確收發(20個元素的字元陣列,更多字元的接收沒有測試。。。)
參考資料:普通的 http://www.eeworld.com.cn/mcu/article_2016053126671.html