我現在因為一些事情需要使用單片機來編程,以前了解過一點51,簡單用過arduino,對編程的精髓不了解,現在必須使用32了,完全懵了。
我現在需要使用32的USART1接電腦,USART2連接一個SIM卡模塊,(硬體已經連接好了,并且是在一塊板子上USART2沒有接出來,無法確定狀態。)我需要寫一段代碼來完成 這中間AT指令的轉發。從USART1接收到的資料轉發給USART2,同時等待USART2回傳資料,然后再通過USART1發送給電腦,就相當于32做了一個中繼。
我現在毫無頭緒,有人來指點下 這個程式的 編程思路應該怎么樣的,例如使不使用中斷,或者在主函式內順序執行。
uj5u.com熱心網友回復:
很簡單,UART1給介面接收到的資料,原樣傳遞給UART2,UART2接收的資料原樣轉發UART1uj5u.com熱心網友回復:
我也是這么想的,但是 每成功啊uj5u.com熱心網友回復:
stm32 的串口代碼網上很多,找一個參考下,分別把每個串口的收發除錯好就簡單了uj5u.com熱心網友回復:
串口1的初始化 中斷等等已經測驗沒問題,但是串口2 沒外接,并且,我現在是卡在了 怎么讓兩個串口交換資料uj5u.com熱心網友回復:
接收的資料保存在陣列里,呼叫發送函式不就行了。在串口1的接收中斷里,呼叫串口2的發送函式,在串口2的接收中斷里,呼叫串口1的發送函式。uj5u.com熱心網友回復:
采用接受中斷簡單一些,usart1接受中斷程式直接啟動USART2發送,把接受到的位元組轉發就成同樣,USART2接受中斷,啟動USART1的發送,直接轉發。
uj5u.com熱心網友回復:
6 樓正解。uj5u.com熱心網友回復:
我做過一個模塊是,跟你的差不多,uart口1 就收到的原樣發給uart2 ,uart2接DTU的模塊(插入SIM卡可以上公網的那種) uart2的自動的去做初始化 和鏈接基站的(包括重連)的動作 ,然后檢測到uart1有資料過來就將包轉成AT指令的通過DTU模塊轉出去,uart2 接收的資料在將AT部分解掉再轉給uart1,整個設備的引數包括IP地址,埠之類的通過uart1設定。(整個模塊的功能實際上就是串口轉網路的功能,專案上要用 網上買一個這個玩意要500塊左右,所以就自己做了)uj5u.com熱心網友回復:
先把各自串口的收發做成功,然后轉發就簡單多了,網上很uj5u.com熱心網友回復:
單片機串口,一般都是采用主動發送,中斷接受! 你這里面,兩個串口接受中斷,接收到資料后,單片機轉發。當然,還可以考慮DMA,不過我沒有試過可以還是不可以。如果可以,你配置好通道,然后就可以什么都不用做了!uj5u.com熱心網友回復:
先用串口助手這些工具調通每一個串口,電腦的串口助手自不必說,stm32的兩個串口的收發都調通,然后是sim卡,我不知道你這個sim卡的串口有沒有回復資訊;sim卡也是有回應的是不是,用串口助手簡單除錯一下看看能不能正常作業就可以了。然后你再考慮整體怎么做 #3#6已經給出方法了uj5u.com熱心網友回復:
重定向可以吧uj5u.com熱心網友回復:
1、開啟第二個串口的接收中斷,判斷接收完成之后發送2、開啟第二串口的接收中斷,設定標志位;在主回圈里面不斷訪問這個標志位,當標志位顯示完成之后,開始發送
主回圈函式:
void uart2_tips(void)
{
if(USART2_RX_STA&0x8000)
{
len=USART2_RX_STA&0x3fff; //得到此次接收到的資料長度
printf("\r\n您發送的USART2訊息為:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART2_RX_BUF[t]);//向串口1發送資料
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束
}
command_operate(USART2_RX_BUF,USART2_RX_STA);
printf("\r\n\r\n");//插入換行
USART2_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nSTM32 USART2\r\n");
}
delay_ms(10);
}
}
串口二中斷處理函式(仿照正點原子的例程):
void USART2_IRQHandler(void) //串口1中斷服務程式
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中斷(接收到的資料必須是0x0d 0x0a結尾)
{
Res =USART_ReceiveData(USART2); //讀取接收到的資料
if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x24)USART2_RX_STA=0;//接收錯誤,重新開始
else USART2_RX_STA|=0x8000; //接收完成了
}
else //還沒收到0X0D
{
if(Res==0x24)
USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
USART2_RX_STA++;
if(USART2_RX_STA>(USART_REC_LEN-1))USART2_RX_STA=0;//接收資料錯誤,重新開始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntExit();
#endif
}
串口2設定:
void uart2_init(u32 bound){
//GPIO埠設定
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的引數初始化VIC暫存器
//USART 初始化設定
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬體資料流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
USART_Init(USART2, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
USART_Cmd(USART2, ENABLE); //使能串口1
}
uj5u.com熱心網友回復:
溫馨提示一下,單片機發送AT指令有一個特別的地方,就是結尾必須是0A 0A 0D,也就是必須發送"\r\n",只是"\n"的話是無效的uj5u.com熱心網友回復:
不準確,確切地說,結尾必須是0x0A,即'\r'
參見《SIM800 Series_AT Command Manual_V1.09》
1.4 AT Command syntax
The "AT" or "at" or “aT” or “At”prefix must be set at the beginning of each Command line. To terminate a Command line enter <CR>.
uj5u.com熱心網友回復:
嗯,當時一下子把0D和0A記混了,卻是是0A結尾,但我強調的不是這點,是必須要有兩個0D再加0A才能被ESP8266識別,否則回傳error
uj5u.com熱心網友回復:
小白學習一下轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241597.html
標籤:單片機/工控
上一篇:求stm32溫度報警器的代碼
下一篇:溶解效果請教
