|
- #include "RS485.h"
- // 變量定義:
- uint8_t USART_TX_BUF[64]; //串口數據發送緩存數組(最大可發送64字節數據)
- /*******************************************************************************
- 函數名稱:Modbus協議CRC校驗函數
- 輸入參數:buf 指向要校驗的數據緩存區基址
- 輸入參數:len 要校驗的字節數
- 返回參數:CRC 校驗結果
- 注意事項:無
- ********************************************************************************/
- static uint16_t CRC_16(uint8_t *buf,uint8_t len)
- {
- uint16_t CRC16 = 0xFFFF;
- uint8_t i, j;
-
- for (i = 0; i < len; i++)
- {
- CRC16 ^= buf[i] ;
- for (j = 0; j < 8; j++)
- {
- if ((CRC16 & 0x0001) != 0){CRC16 = (CRC16>>1)^0xA001;}
- else{CRC16 >>= 1;}
- }
- }
- return CRC16;
- }
- /*******************************************************************************
- 函數名稱:RS485數據緩存區初始化函數
- 輸入參數:buf 指向要初始化緩存區的基址
- 輸入參數:data 要初始化的數值(一般初始化的值為0x00)
- 輸入參數:len 要初始化的字節長度
- 返回參數:無
- 注意事項:無
- ********************************************************************************/
- static void Arry_Init(uint8_t *buf,uint8_t data,uint8_t len)
- {
- uint8_t i; //索引變量
- for(i=0;i<len;i++) //執行相應次數的字節空間初始化
- {
- buf[i] = data; //字節空間初始化
- }
- }
- /*******************************************************************************
- 函數名稱:RS485串口參數配置函數
- 輸入參數:無
- 返回參數:無
- 注意事項:無
- ********************************************************************************/
- void RS485_USART_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure; //定義GPIO外設初始化結構體
- USART_InitTypeDef USART_InitStructure; //定義USART外設初始化結構體
-
- USART_APBxClkCmd( USART_CLK, ENABLE ); //使能APB2高速USART1外設時鐘
- USART_GPIO_APBxClkCmd( USART_GPIO_CLK,ENABLE ); //使能APB2高速GPIOA外設時鐘
- RS485_GPIO_APBxClkCmd( RS485_GPIO_CLK,ENABLE ); //使能接收發送引腳時鐘
-
- //配置發送引腳Tx
- GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; //配置GPIO端口
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //配置為復用推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口速度配置為50MHz
- GPIO_Init( USART_TX_PORT,&GPIO_InitStructure ); //端口初始化
-
- //配置接收引腳Rx
- GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; //配置GPIO端口
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置為浮空輸入
- GPIO_Init(USART_RX_PORT,&GPIO_InitStructure); //端口初始化
-
- //配置接收或發送使能引腳
- GPIO_InitStructure.GPIO_Pin = RS485_GPIO_PIN; //配置GPIO端口
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置為推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口速度配置為50MHz
- GPIO_Init( RS485_GPIO_PORT,&GPIO_InitStructure ); //端口初始化
-
- //配置串口外設
- USART_InitStructure.USART_Mode = USART_Mode_Tx; //配置串口為發送模式
- USART_InitStructure.USART_BaudRate = USART_BAUD; //配置串口波特率
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //配置串口硬件控制流
- USART_InitStructure.USART_Parity = USART_Parity_No; //配置校驗位為無校驗
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //配置串口為一個停止位
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //八位數據幀模式
- USART_Init(USARTx, &USART_InitStructure); //USART初始化
-
- USART_ClearFlag(USARTx, USART_FLAG_TC); //清除發送完畢標志位TC
-
- USART_Cmd( USARTx,ENABLE ); //使能串口
- RS485_TXorRX_EN( TX_EN ); //接收或發送使能引腳默認為接收狀態
- }
- /*******************************************************************************
- 函數名稱:RS485串口發送函數
- 輸入參數:buf 指向數據發送緩存區的首地址
- 輸入參數:len 指定發送的數據長度
- 返回參數:無
- 注意事項:無
- ********************************************************************************/
- void RS485_SendData(uint8_t *buf,uint8_t len)
- {
- uint8_t i = 0; //索引變量
-
- RS485_TXorRX_EN( TX_EN ); //使能為發送模式
- Delay_ms(3);
- for(i=0;i<len;i++) //按照相應長度循環發送數據
- {
- while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET); //檢測是否發送完畢
- USART_SendData(USARTx,buf[i]); //將指向的數據發送
- }
- while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET); //檢測是否發送完畢
- }
- ///*******************************************************************************
- //函數名稱:Modbus協議主機發送0x03(讀寄存器)命令函數
- //輸入參數:addr 要發送命令的從機設備地址
- //輸入參數:startable 要讀取的從機寄存器起始地址
- //輸入參數:len 要讀取的寄存器個數
- //返回參數:無
- //注意事項:無
- //********************************************************************************/
- //void Modbus_Send_0x03Cmd(uint8_t addr,uint16_t startaddr,uint16_t len)
- //{
- // if(len > 0x14){len = 0x14;} //讀取的寄存器個數只允許讀20個,超出按最大20個讀取(寄存器個數的最大值要根據接收緩存區的大小來決定,可人為定義寄存器個數的最大值)
- // USART_TX_BUF[0] = addr; //獲取從機設備地址
- // USART_TX_BUF[1] = 0x03; //獲取讀寄存器功能碼(0x03)
- // USART_TX_BUF[2] = (uint8_t)(startaddr>>8); //獲取寄存器基址高字節
- // USART_TX_BUF[3] = (uint8_t)(startaddr&0xFF); //獲取寄存器基址低字節
- // USART_TX_BUF[4] = (uint8_t)(len>>8); //獲取讀取寄存器個數高字節
- // USART_TX_BUF[5] = (uint8_t)(len&0xFF); //獲取讀取寄存器個數低字節
- // ((uint16_t)*(USART_TX_BUF+6)) = CRC_16(USART_TX_BUF,6);//獲取發送數據的CRC校驗結果
- // RS485_SendData(USART_TX_BUF,8); //發送讀寄存器功能命令
- // USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //發送完畢,開串口接收中斷
- //}
- /*******************************************************************************
- 函數名稱:Modbus協議主機發送0x06(寫單個寄存器)命令函數
- 輸入參數:addr 要發送命令的從機設備地址
- 輸入參數:startable 要發送的從機寄存器起始地址
- 輸入參數:Data 要寫入的數據
- 返回參數:無
- 注意事項:無
- ********************************************************************************/
- void Modbus_Send_0x06Cmd(uint8_t addr,uint16_t startaddr,uint16_t Data)
- {
- unsigned short temp;
-
- USART_TX_BUF[0] = addr; //獲取從機設備地址
- USART_TX_BUF[1] = 0x06; //獲取讀寄存器功能碼(0x06)
- USART_TX_BUF[2] = (uint8_t)(startaddr>>8); //獲取寄存器基址高字節
- USART_TX_BUF[3] = (uint8_t)(startaddr&0xFF); //獲取寄存器基址低字節
- USART_TX_BUF[4] = (uint8_t)(Data>>8); //獲取寫入數據的高字節
- USART_TX_BUF[5] = (uint8_t)(Data&0xFF); //獲取寫入數據的低字節
- temp = CRC_16( USART_TX_BUF,6 );
- USART_TX_BUF[6] = (uint8_t)(temp&0xFF);
- USART_TX_BUF[7] = (uint8_t)(temp>>8);
- RS485_SendData(USART_TX_BUF,8); //發送讀寄存器功能命令
- }
- ///*******************************************************************************
- //函數名稱:Modbus協議主機發送0x10(寫多個寄存器)命令函數
- //輸入參數:addr 要發送命令的從機設備地址
- //輸入參數:startable 要寫入的從機寄存器起始地址 (范圍:0~64)
- //輸入參數:len 要寫入的寄存器個數 (范圍:0~255)
- //輸入參數:buf 指向要發送的數據緩存區
- //返回參數:無
- //注意事項:無
- //********************************************************************************/
- //void Modbus_Send_0x10Cmd(uint8_t addr,uint16_t startaddr,uint16_t len,uint16_t *buf)
- //{
- // uint8_t i = 0; //索引變量
- //
- // USART_TX_BUF[0] = addr; //獲取從機設備地址
- // USART_TX_BUF[1] = 0x10; //獲取寫多個寄存器功能碼(0x10)
- // USART_TX_BUF[2] = (uint8_t)(startaddr>>8); //獲取寄存器基址高字節
- // USART_TX_BUF[3] = (uint8_t)(startaddr&0xFF); //獲取寄存器基址低字節
- // USART_TX_BUF[4] = (uint8_t)(len>>8); //獲取寫入數據寄存器個數高字節
- // USART_TX_BUF[5] = (len&0xFF); //獲取寫入數據寄存器個數低字節
- // USART_TX_BUF[6] = (uint8_t)(len*2); //獲取數據的總字節數
- // for(i=0;i<USART_TX_BUF[5];i++) //循環獲取要發送的數據
- // {
- // USART_TX_BUF[7+(i*2)] = (uint8_t)(buf[i]>>8);
- // USART_TX_BUF[8+(i*2)] = (uint8_t)(buf[i]&0xFF);
- // }
- // ((uint16_t)(USART_TX_BUF+(7+USART_TX_BUF[6]))) = CRC_16(USART_TX_BUF,(7+USART_TX_BUF[6])); //獲取發送數據的CRC校驗結果
- // RS485_SendData(USART_TX_BUF,(9+USART_TX_BUF[6])); //發送寫多個寄存器功能命令
- //}
- #include "stm32f10x.h"
- #include "RS485.h"
- #include "Delay.h"
- void GPIO_Cofing( void );
- /*******************************************************************************
- 函數名稱:主函數
- 輸入參數:無
- 返回參數:無
- 注意事項:無
- ********************************************************************************/
- int main(void)
- {
- Delay_Init();
- RS485_USART_Config();
- GPIO_Cofing();
- while(1)
- {
- Modbus_Send_0x06Cmd(0x01,0x2000,0x0001); //發送電機正轉信號
- Delay_ms(20000);
- // Modbus_Send_0x06Cmd(0x01,0x2001,0x0002); //發送電機正轉信號
- // Delay_ms(1000);
- }
- }
- void GPIO_Cofing( void )
- {
- GPIO_InitTypeDef GPIO_InitStructure; //定義GPIO外設初始化結構體
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE );
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_Init( GPIOA, &GPIO_InitStructure );
-
- GPIO_SetBits( GPIOA, GPIO_Pin_6 );
- Delay_ms(3000);
- }
復制代碼
|
|