久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標(biāo)題:
stm32 modbus通信程序 485觸摸屏、工控屏 開發(fā)很好用
[打印本頁]
作者:
yuguoyu123456
時間:
2019-7-23 20:27
標(biāo)題:
stm32 modbus通信程序 485觸摸屏、工控屏 開發(fā)很好用
stm32 modbus通信 觸摸屏、工控屏 開發(fā)很好用!!!
單片機(jī)源程序如下:
#include "rs485.h"
#include "SysTick.h"
#include "crc16.h"
#include "led.h"
/*******************************************************************************
* 函 數(shù) 名 : RS485_Init
* 函數(shù)功能 : USART2初始化函數(shù)
* 輸 入 : bound:波特率
* 輸 出 : 無
*******************************************************************************/
u8 USART2_RX_BUF[64]; //接收緩沖,最大64字節(jié)
u8 USART2_RX_CNT=0; //接收字節(jié)計數(shù)器
u8 flagFrame=0; //幀接收完成標(biāo)志,即接收到一幀新數(shù)據(jù)
unsigned char regGroup[5]; //Modbus寄存器組,地址為0x00~0x04
void RS485_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA\G時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2時鐘
/* 配置GPIO的模式和IO口 */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; //TX-485 //串口輸出PA2
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化串口輸入IO */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3; //RX-485 //串口輸入PA3
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模擬輸入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3; //CS-485
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOG,&GPIO_InitStructure);
//USART2 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//波特率設(shè)置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口 2
USART_ClearFlag(USART2, USART_FLAG_TC);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟接受中斷
//Usart2 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //子優(yōu)先級2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器、
RS485_TX_EN=0; //默認(rèn)為接收模式
}
//1ms定時
void TIM2_Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//使能TIM4時鐘
TIM_TimeBaseInitStructure.TIM_Period=1000; //自動裝載值
TIM_TimeBaseInitStructure.TIM_Prescaler=72-1; //分頻系數(shù)
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //設(shè)置向上計數(shù)模式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //開啟定時器中斷
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定時器中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2,ENABLE); //使能定時器
}
//計算發(fā)送的數(shù)據(jù)長度,并且將數(shù)據(jù)放到*buf數(shù)組中
u8 UartRead(u8 *buf, u8 len)
{
u8 i;
if(len>USART2_RX_CNT) //指定讀取長度大于實(shí)際接收到的數(shù)據(jù)長度時
{
len=USART2_RX_CNT; //讀取長度設(shè)置為實(shí)際接收到的數(shù)據(jù)長度
}
for(i=0;i<len;i++) //拷貝接收到的數(shù)據(jù)到接收指針中
{
*buf=USART2_RX_BUF[i]; //將數(shù)據(jù)復(fù)制到buf中
buf++;
}
USART2_RX_CNT=0; //接收計數(shù)器清零
return len; //返回實(shí)際讀取長度
}
u8 rs485_UartWrite(u8 *buf ,u8 len) //發(fā)送
{
u8 i=0;
GPIO_SetBits(GPIOG,GPIO_Pin_3); //發(fā)送模式
delay_ms(3); //3MS延時
for(i=0;i<=len;i++)
{
USART_SendData(USART2,buf[i]); //通過USARTx外設(shè)發(fā)送單個數(shù)據(jù)
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); //檢查指定的USART標(biāo)志位設(shè)置與否,發(fā)送數(shù)據(jù)空位標(biāo)志
}
GPIO_ResetBits(GPIOG,GPIO_Pin_3); //設(shè)置為接收模式
}
//串口驅(qū)動函數(shù),檢測數(shù)據(jù)幀的接收,調(diào)度功能函數(shù),需在主循環(huán)中調(diào)用
void UartDriver()
{
unsigned char i=0,cnt;
unsigned int crc;
unsigned char crch,crcl;
static u8 len;
static u8 buf[60];
if(flagFrame) //幀接收完成標(biāo)志,即接收到一幀新數(shù)據(jù)
{
flagFrame=0; //幀接收完成標(biāo)志清零
len = UartRead(buf,sizeof(buf)); //將接收到的命令讀到緩沖區(qū)中
if(buf[0]==0x01) //判斷地址是不是0x01
{
crc=GetCRC16(buf,len-2); //計算CRC校驗(yàn)值,出去CRC校驗(yàn)值
crch=crc>>8; //crc高位
crcl=crc&0xFF; //crc低位
if((buf[len-2]==crch)&&(buf[len-1]==crcl)) //判斷CRC校驗(yàn)是否正確
{
switch (buf[1]) //按功能碼執(zhí)行操作
{
case 0x03: //讀數(shù)據(jù)
if((buf[2]==0x00)&&(buf[3]<=0x05)) //寄存器地址支持0x0000~0x0005
{
if(buf[3]<=0x04)
{
i=buf[3];//提取寄存器地址
cnt=buf[5]; //提取待讀取的寄存器數(shù)量
buf[2]=cnt*2; //讀取數(shù)據(jù)的字節(jié)數(shù),為寄存器*2,因modbus定義的寄存器為16位
len=3;
while(cnt--)
{
buf[len++]=0x00; //寄存器高字節(jié)補(bǔ)0
buf[len++]=regGroup[i++]; //低字節(jié)
}
}
break;
}
else //寄存器地址不被支持時,返回錯誤碼
{
buf[1]=0x83; //功能碼最高位置1
buf[2]=0x02; //設(shè)置異常碼為02-無效地址
len=3;
break;
}
case 0x06: //寫入單個寄存器
if((buf[2]==0x00)&&(buf[3]<=0x05)) //寄存器地址支持0x0000-0x0005
{
if(buf[3]<=0x04)
{
i=buf[3]; //提取寄存器地址
regGroup[i]=buf[5]; //保存寄存器數(shù)據(jù)
led3=0;
}
len -=2; //長度-2以重新計算CRC并返回原幀
break;
}
else
{ //寄存器地址不被支持,返回錯誤碼
buf[1]=0x86; //功能碼最高位置1
buf[2]=0x02; //設(shè)置異常碼為02-無效地址
len=3;
break;
}
default: //其他不支持的功能碼
buf[1]=0x80; //功能碼最高位置1
buf[2]=0x01; //設(shè)置異常碼為01—無效功能
len=3;
break;
}
crc=GetCRC16(buf,len); //計算CRC校驗(yàn)值
buf[len++]=crc>>8; //CRC高字節(jié)
buf[len++]=crc&0xff; //CRC低字節(jié)
rs485_UartWrite(buf,len); //發(fā)送響應(yīng)幀
}
}
}
}
void UartRxMonitor(u8 ms) //串口接收監(jiān)控
{
static u8 USART2_RX_BKP=0; //定義USART2_RC_BKP暫時存儲詩句長度與實(shí)際長度比較
static u8 idletmr=0; //定義監(jiān)控時間
if(USART2_RX_CNT>0)//接收計數(shù)器大于零時,監(jiān)控總線空閑時間
{
if(USART2_RX_BKP!=USART2_RX_CNT) //接收計數(shù)器改變,即剛接收到數(shù)據(jù)時,清零空閑計時
{
USART2_RX_BKP=USART2_RX_CNT; //賦值操作,將實(shí)際長度給USART2_RX_BKP
idletmr=0; //將監(jiān)控時間清零
}
else ////接收計數(shù)器未改變,即總線空閑時,累計空閑時間
{
//如果在一幀數(shù)據(jù)完成之前有超過3.5個字節(jié)時間的停頓,接收設(shè)備將刷新當(dāng)前的消息并假定下一個字節(jié)是一個新的數(shù)據(jù)幀的開始
if(idletmr<5) //空閑時間小于1ms時,持續(xù)累加
{
idletmr +=ms;
if(idletmr>=5) //空閑時間達(dá)到1ms時,即判定為1幀接收完畢
{
flagFrame=1;//設(shè)置命令到達(dá)標(biāo)志,幀接收完畢標(biāo)志
}
}
}
}
else
{
USART2_RX_BKP=0;
}
}
/*******************************************************************************
* 函 數(shù) 名 : USART2_IRQHandler
* 函數(shù)功能 : USART2中斷函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void USART2_IRQHandler(void)
{
u8 res; //定義數(shù)據(jù)緩存變量
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收到數(shù)據(jù)
{
res =USART_ReceiveData(USART2);//;讀取接收到的數(shù)據(jù)USART2->DR
if(USART2_RX_CNT<sizeof(USART2_RX_BUF)) //一次只能接收64個字節(jié),人為設(shè)定,可以更大,但浪費(fèi)時間
{
USART2_RX_BUF[USART2_RX_CNT]=res; //記錄接收到的值
USART2_RX_CNT++; //使收數(shù)據(jù)增加1
}
}
}
/*******************************************************************************
* 函 數(shù) 名 : TIM2_IRQHandler
* 函數(shù)功能 : TIM2中斷函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void TIM2_IRQHandler(void)
{
UartRxMonitor(1); ////串口接收監(jiān)控
led2=!led2; //指示燈
//delay_ms(100);
TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //更新中斷
}
復(fù)制代碼
所有資料51hei提供下載:
ModBus-Master.7z
(201.85 KB, 下載次數(shù): 304)
2019-7-24 04:47 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
stm32+RS485.7z
(179.63 KB, 下載次數(shù): 328)
2019-7-24 04:47 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
admin
時間:
2019-7-24 04:48
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
作者:
zk115
時間:
2019-7-25 21:32
感謝分享。正好最近在做相關(guān)軟件
作者:
sishen00
時間:
2020-9-11 23:13
感謝分享。正好最近在做相關(guān)軟件
作者:
liangdong1
時間:
2020-9-12 15:15
感謝分享。正好最近在做相關(guān)軟件
作者:
51heixc
時間:
2020-9-13 10:29
感謝正在學(xué)習(xí)相關(guān)知識
作者:
ljfong
時間:
2020-10-31 22:55
其實(shí)程序不重要,重要的是理論知識
作者:
tianwudalu
時間:
2021-11-22 14:27
感謝正在學(xué)習(xí)相關(guān)知識
作者:
he200312
時間:
2021-12-9 13:35
感謝分享。正好最近在做相關(guān)軟件
作者:
1234578zqq
時間:
2024-7-27 15:45
感謝分享。正好最近在做相關(guān)軟件
作者:
huaishang
時間:
2024-7-28 18:50
感謝正在學(xué)習(xí)相關(guān)知識
作者:
秋風(fēng)涼
時間:
2024-9-15 15:48
感謝正在學(xué)習(xí)相關(guān)知識
作者:
huaishang
時間:
2025-4-19 09:53
感謝正在學(xué)習(xí)相關(guān)知識
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
久在线
|
国产一区二区在线播放
|
久久91
|
久久免费资源
|
黄色在线免费观看
|
免费一区二区
|
亚洲成人精品免费
|
91 在线
|
国产一区二区三区久久久久久久久
|
91精品国产自产在线老师啪
|
国产中文原创
|
日韩av成人在线观看
|
久久亚洲欧美日韩精品专区
|
一本一道久久a久久精品综合
|
日韩午夜网站
|
久久精品视频播放
|
美女视频三区
|
亚洲成人国产综合
|
国产一区二区精品在线
|
91精品久久久久久久久99蜜臂
|
福利网址
|
超碰在线久
|
亚洲一区中文字幕
|
欧美日韩三区
|
五月天激情电影
|
在线免费观看黄网
|
久久久久91
|
亚洲视频中文字幕
|
欧美视频在线播放
|
91在线电影
|
一区免费
|
久一久
|
午夜天堂精品久久久久
|
www久久99
|
国产美女在线精品免费
|
一级片在线播放
|
欧产日产国产精品99
|
国产精品久久久久久久久久
|
伊人性伊人情综合网
|
在线观看国产视频
|
五月婷婷色
|