欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: 求指點(diǎn)STM32 RS485發(fā)送幀數(shù)據(jù)更好的方法 附源程序 [打印本頁(yè)]

作者: 我,菜雞    時(shí)間: 2022-3-11 07:37
標(biāo)題: 求指點(diǎn)STM32 RS485發(fā)送幀數(shù)據(jù)更好的方法 附源程序
不知道是不是因?yàn)槲业姆椒ú缓侠,使用了while()循環(huán)來(lái)485發(fā)送幀數(shù)據(jù)的時(shí)候,數(shù)碼管會(huì)閃爍,普通串口不會(huì),不知道問(wèn)題是不是在while()這里。

//485收發(fā)上圖:

貼代碼(stm32f103ret6):
//main.c
#include "stm32f10x.h"                  // Device header
#include "LED.H"
#include "DISPLAY.H"
#include "TIMER.H"
#include "USART.H"
#include "RS485.H"

int main(void)
{
        LED_Init();
        DISPLAY1_Init();
        KEY_Init();
        INTERRUPT_Init();
        Timer_Init();
        USART1_Init();
        RS485_Init();
        
        while (1)
        {
               
        }        
}



//rs485.h
#ifndef __RS485_H
#define __RS485_H

void RS485_Init(void);

extern unsigned int Uart4_Rx;
extern unsigned char Uart4_Buffer[ ];
extern uint16_t Uart4_Tx_Num;

#endif


//rs485.c
#include "stm32f10x.h"                  // Device header
#include "DISPLAY.H"
        //RS485(UART4) : TX/PC10; RX/PC11; DE/PA12。
void RS485_Init(void)
{
                //GPIO_配置UART4_DE(PA12);并初始化為低電平,UART4_485為接收模式。
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        //開(kāi)啟對(duì)應(yīng)GPIO_時(shí)鐘
        GPIO_InitTypeDef GPIO_InitStructure;        //定義GPIO_結(jié)構(gòu)體
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;               
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA, GPIO_Pin_12);        //初始化UART4_DE為低電平,UART4_485默認(rèn)為接收模式。
                //GPIO_配置UART4_TX(PC10)
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);        //開(kāi)啟對(duì)應(yīng)GPIO_時(shí)鐘
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);        
                //GPIO_配置UART4_RX(PC11)
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        
                //USART_配置UART4(波特率9600,長(zhǎng)度8字節(jié),1停止位,0奇偶校驗(yàn)位,0硬件流控制)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);        //開(kāi)啟對(duì)應(yīng)USART_時(shí)鐘
        USART_InitTypeDef USART_InitStructure;        //定義USART_結(jié)構(gòu)體
        USART_InitStructure.USART_BaudRate = 9600;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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;                //使能發(fā)送與接收功能
        USART_Init(UART4, &USART_InitStructure);
        USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);        //接收中斷,使能
        USART_ITConfig(UART4, USART_IT_IDLE, ENABLE);        //空閑總線中斷,使能
        USART_Cmd(UART4, ENABLE);        //使設(shè)定的配置生效,但在STM32里,需要配合對(duì)應(yīng)的時(shí)鐘使用
        
                //NVIC_配置UART4(優(yōu)先級(jí)分組2,搶占優(yōu)先級(jí)為1,響應(yīng)優(yōu)先級(jí)為1)
        NVIC_InitTypeDef NVIC_InitStructure;        //定義NVIC_結(jié)構(gòu)體
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                   
        NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
        NVIC_Init(&NVIC_InitStructure);                                 
}

#define Max_BUFF_Len_4 18
unsigned char Uart4_Buffer[ Max_BUFF_Len_4 ];

unsigned int Uart4_Rx = 0;
void UART4_ReceiveData(void)
{
        if(USART_GetITStatus (UART4,USART_IT_RXNE))                //接收中斷
        {
                Uart4_Buffer[ Uart4_Rx ] = USART_ReceiveData(UART4);
                Uart4_Rx ++;
                if(Uart4_Rx >=201)        //防止達(dá)數(shù)組上限
                {
                        Uart4_Rx = 0;
                }
        }
}

uint16_t Uart4_Tx_Num =0;
void UART4_TX(void)
{
        static uint32_t Clear;
        if(USART_GetITStatus (UART4,USART_IT_IDLE))                //總線空閑中斷   
        {
                while(Uart4_Rx >=1)                //485循環(huán)發(fā)送數(shù)組Uart4_Buffer[ ]內(nèi)的數(shù),解決只一次發(fā)送的問(wèn)題
                {
                        GPIO_SetBits(GPIOA, GPIO_Pin_12);        //485發(fā)送使能
                        USART_SendData(UART4,Uart4_Buffer[ Uart4_Tx_Num ]);
                        Uart4_Tx_Num ++;        //485發(fā)送順序從數(shù)組Uart4_Buffer[ 0-100 ]
                        while(USART_GetFlagStatus (UART4,USART_FLAG_TC) !=1);
                        if(Uart4_Tx_Num == Uart4_Rx )        //        待發(fā)送完成
                        {
                                Uart4_Rx = 0;
                                Uart4_Tx_Num = 0;
                        }
                }
                if(Uart4_Rx ==0)
                {
                        Clear = UART4->SR;        //跳出總線空閑中斷
                        Clear = UART4->DR;        //跳出總線空閑中斷
                        GPIO_ResetBits(GPIOA, GPIO_Pin_12);
                }
        }
}

void UART4_IRQHandler(void)
{
        UART4_ReceiveData();
        UART4_TX();
        
        USART_ClearFlag (UART4,USART_FLAG_TC);
}



//usart.h
#ifndef __USART_H
#define __USART_H

void USART1_Init(void);

extern unsigned int Usart1_Rx;
extern unsigned char Usart1_Buffer[ ];


#endif


//usart.c
#include "stm32f10x.h"   

        //USART1 : TX/PA9; RX/PA10。
void USART1_Init(void)
{
                //GPIO_配置USART1_TX(PA9)               
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA ,ENABLE );          //GPIOA時(shí)鐘開(kāi)啟
        GPIO_InitTypeDef GPIO_InitInstructure;        
        GPIO_InitInstructure.GPIO_Mode = GPIO_Mode_AF_PP;          //選擇引腳模式,TX 需配置為:_AF_PP(復(fù)用推挽輸出,用作串口的輸出)
        GPIO_InitInstructure.GPIO_Pin = GPIO_Pin_9;          //選擇引腳
        GPIO_InitInstructure.GPIO_Speed = GPIO_Speed_50MHz;          //選擇引腳頻率
        GPIO_Init(GPIOA,&GPIO_InitInstructure );        //進(jìn)行參數(shù)初始化
                //GPIO_配置USART1_RX(PA10)
        GPIO_InitInstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //選擇引腳模式,RX 需配置為:_IN_FLOATING(浮空輸入,由于其輸入阻抗比較大,一般把這種模式用于標(biāo)準(zhǔn)的通訊協(xié)議,比如IIC、USART等)
        GPIO_InitInstructure.GPIO_Pin = GPIO_Pin_10;          //選擇引腳
        GPIO_InitInstructure.GPIO_Speed = GPIO_Speed_50MHz;          //RX引腳,也可以不配置引腳頻率
        GPIO_Init(GPIOA,&GPIO_InitInstructure );        //進(jìn)行參數(shù)初始化
        
                //USART_配置USART1(波特率9600,長(zhǎng)度8字節(jié),1停止位,0奇偶校驗(yàn)位,0硬件流控制)
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1 ,ENABLE );        //串口USART1時(shí)鐘開(kāi)啟
        USART_InitTypeDef USART_InitInstructure;
        USART_InitInstructure.USART_BaudRate = 9600;        //直接修改波特率即可
        USART_InitInstructure.USART_WordLength = USART_WordLength_8b;        //長(zhǎng)度 8字節(jié)
        USART_InitInstructure.USART_StopBits = USART_StopBits_1;        //1位 停止位
        USART_InitInstructure.USART_Parity = USART_Parity_No;        //無(wú) 奇偶校驗(yàn)位
        USART_InitInstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //無(wú) 硬件流控制
        USART_InitInstructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //使能發(fā)送與接收功能
        USART_Init(USART1,&USART_InitInstructure);
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);        //接收中斷,使能
        USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);        //總線空閑中斷,使能               
        USART_Cmd (USART1 ,ENABLE );        //使設(shè)定的配置生效,但在STM32里,需要配合對(duì)應(yīng)的時(shí)鐘使用

                //NVIC_配置USART1(優(yōu)先級(jí)分組2,搶占優(yōu)先級(jí)為2,響應(yīng)優(yōu)先級(jí)為2)
        NVIC_InitTypeDef NVIC_InitStructure;        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;        //從stm32f10x.h里第243-268行選擇
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        //搶占優(yōu)先級(jí)為2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //響應(yīng)優(yōu)先級(jí)為2
        NVIC_Init(&NVIC_InitStructure);          //進(jìn)行參數(shù)初始化
}

#define Max_BUFF_Len_1 18
unsigned char Usart1_Buffer[ Max_BUFF_Len_1 ];

unsigned int Usart1_Rx = 0;

void USART1_IRQHandler(void)
{
        if(USART_GetITStatus (USART1,USART_IT_RXNE))        //接收中斷
        {
                Usart1_Buffer[ Usart1_Rx ] = USART_ReceiveData(USART1);
                Usart1_Rx ++;
               
                USART_SendData(USART1,Usart1_Buffer[ Usart1_Rx -1 ]);  //接收完立即發(fā)
               
                Usart1_Rx = 0;
        }
        
        USART_ClearFlag (USART1,USART_FLAG_TC);
}



//TIMER.H
#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);
void TIM2_IRQHandler(void);

extern uint16_t k;


#endif


//TIMER.c
#include "stm32f10x.h"                  // Device header
#include "DISPLAY.H"

void Timer_Init(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //開(kāi)啟TIM2時(shí)鐘
        
        TIM_InternalClockConfig(TIM2);        //
        //計(jì)數(shù)器溢出頻率CK_CNT_OV = CK_CNT / (ARR + 1)= CK_PSC / (PSC + 1) / (ARR + 1)
        //內(nèi)部時(shí)鐘默認(rèn)為72M,此處選用內(nèi)部時(shí)鐘頻率的話
        //若設(shè)置為72M/(7200-1 +1) /(10000-1 +1) = 1秒,即:1秒進(jìn)中斷一次。
        //結(jié)構(gòu)體(TIM_TimeBaseInitStructure),在本函數(shù)內(nèi)定義一次即可
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;         //
        TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;          //濾波采樣分頻系數(shù),1/2/4分頻。它影響的是濾波器的采樣(輸入)頻率,與輸出無(wú)關(guān)
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;          //TIM向上計(jì)數(shù)模式
        TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;          //定時(shí)器預(yù)分頻器設(shè)置,可設(shè)置范圍為 0 至 65535,實(shí)現(xiàn) 1 至 65536 分頻,內(nèi)部自動(dòng)+1。        
        TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;        //定時(shí)器周期,設(shè)定自動(dòng)重載寄存器的值,在事件生成時(shí)更新到影子寄存器?稍O(shè)置范圍為 0 至 65535,內(nèi)部自動(dòng)+1。
        TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;        //高級(jí)定時(shí)器才有的。周期倍數(shù):n+1倍。此處為0時(shí),即1倍周期1s;為1時(shí)即2倍周期2s,n最大為225(0XFF)。
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);         //初始化參數(shù)(TIM)
        
        TIM_ClearFlag(TIM2, TIM_FLAG_Update);        //清除更新中斷,避免一打開(kāi)中斷就立刻產(chǎn)生中斷
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);         //打開(kāi)定時(shí)器更新中斷
        
                //前提條件1:組別優(yōu)先順序(第0組優(yōu)先級(jí)最強(qiáng),第4組優(yōu)先級(jí)最弱):NVIC_PriorityGroup_0>NVIC_PriorityGroup_1>NVIC_PriorityGroup_2>NVIC_PriorityGroup_3>NVIC_PriorityGroup_4
                //前提條件2:不同組優(yōu)先級(jí)別間,依據(jù)優(yōu)先級(jí)強(qiáng)弱,優(yōu)先級(jí)別高的組,其中斷源可以打斷優(yōu)先級(jí)別低的組的正在做的事情;(即:不同組優(yōu)先級(jí)間,可以中斷嵌套)
                //前提條件3:組優(yōu)先級(jí)別>搶占優(yōu)先級(jí)別>響應(yīng)優(yōu)先級(jí)別
                //前提條件4:搶占優(yōu)先級(jí)越小,優(yōu)先級(jí)越高;但同組優(yōu)先級(jí)不能相互打斷,也就沒(méi)有中斷嵌套
                //前提條件5:響應(yīng)優(yōu)先級(jí)越小的中斷首先執(zhí)行(不能嵌套),如果響應(yīng)優(yōu)先級(jí)也均相同,則根據(jù)各中斷對(duì)應(yīng)向量表的位置來(lái)確定,向量表中越靠前的中斷先響應(yīng)
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);          //函數(shù)優(yōu)先級(jí)分組配置,共5組(0-4),此處為第1組。
        
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;          //選擇EXTI2中斷 ,對(duì)應(yīng)之前開(kāi)啟的TIM2時(shí)鐘
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能EXTI2中斷
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        //搶占優(yōu)先級(jí)
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;         //響應(yīng)優(yōu)先級(jí)
        NVIC_Init(&NVIC_InitStructure);          //初始化參數(shù)(NVIC)
        
        TIM_Cmd(TIM2, ENABLE);         //使能TIM2外設(shè)
}

uint16_t k = 1;

void TIM2_IRQHandler(void)
{
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)        //檢查指定的TIM中斷發(fā)生與否
        {
                k ++;
                if(k >= 40)
                {
                        k = 1;
                }
                Display();
               
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                //清除TIM2的中斷待處理位
        }
}



//display.h
#ifndef __DISPLAY_H
#define __DISPLAY_H

void DISPLAY1_Init(void);
void Display(void);


extern uint16_t n;
extern uint16_t p;

#endif


//display.c
#include "stm32f10x.h"                  // Device header
#include "TIMER.H"
#include "USART.H"
#include "RS485.H"

void DISPLAY1_Init(void)        //初始化時(shí)可以設(shè)置為默認(rèn)完全打開(kāi)功能,檢測(cè)硬件是否OK
{
        //PB4:SGE1(位選1);PB3:SEG2(位選2)
        //PC13:a;PC14:b;PC15:c;PC1:d;
        //PC3:e;PA2:f;PA3:g;PC0:dp。
        //GPIO_Write(GPIOC, 0xE00B);
        //GPIO_Write(GPIOA,0x000C);
        //共陰數(shù)碼管:所有陰極(負(fù)極)連在(并在)一起。共陽(yáng)同理。        
                //結(jié)構(gòu)體:
        GPIO_InitTypeDef GPIO_InitStructure;        //定義結(jié)構(gòu)體GPIO_InitStructure,用它來(lái)傳遞數(shù)據(jù)
                //STM32F10x系列的MCU復(fù)位后,PA13/14/15 & PB3/4默認(rèn)配置為JTAG功能。有時(shí)我們?yōu)榱顺浞掷肕CU I/O口的資源,會(huì)把這些端口設(shè)置為普通I/O口
               
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);        //使能相應(yīng)GPIOB端口時(shí)鐘以及AFIO功能時(shí)鐘(復(fù)用時(shí)鐘),在使用時(shí)開(kāi)啟,一方面可以降低功耗;
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);         
                //枚舉類(lèi)型:規(guī)范、限制變量賦值、取值范圍,使其不能隨意取值。
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;        //選擇引腳模式,結(jié)構(gòu)體GPIO_InitStructure內(nèi)枚舉類(lèi)型GPIO_Mode賦值        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4 ;        //選擇引腳,結(jié)構(gòu)體GPIO_InitStructure內(nèi)枚舉類(lèi)型GPIO_Pin賦值
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //選擇引腳頻率,結(jié)構(gòu)體GPIO_InitStructure內(nèi)枚舉類(lèi)型GPIO_Speed賦值
        GPIO_Init(GPIOB,&GPIO_InitStructure);        //進(jìn)行參數(shù)初始化(GPIOB), &:取地址符號(hào),這里使用地址傳遞
        
//        GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4);         //賦值,數(shù)碼管高電平有效,非初始化必需步驟
        
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC ,ENABLE );
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
        GPIO_InitStructure .GPIO_Pin =GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz ;
        GPIO_Init (GPIOC,&GPIO_InitStructure );
        
//        GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13);        //高電平有效
        
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE );
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP ;
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2|GPIO_Pin_3 ;
        GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        
//        GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
}

uint16_t p;
uint16_t n;
        //通過(guò)定時(shí)器內(nèi)k(1-40)的自增循環(huán),來(lái)進(jìn)行數(shù)碼管的點(diǎn)亮刷新
void Display(void)
{
        if(k >= 1 && k <= 19 )
        {
                GPIO_Write(GPIOB, 0x0010 );  //數(shù)碼管位選1
        }
        if(k >= 20 && k <= 39)
        {
                GPIO_Write(GPIOB, 0x0008 );  //數(shù)碼管位選2
        }                                
                //0-9
        const uint16_t num_table_1[] = {0xE00A,0xC000,0x600A,0xE002,0xC000,0xA002,0xA00A,0xE000,0xE00A,0xE002};                //,0x0001
        const uint16_t num_table_2[] = {0x0004,0x0000,0x0008,0x0008,0x000C,0x000C,0x000C,0x0000,0x000C,0x000C};                //,0x0000
                p= 1;//Uart4_Rx / 10 %10 ;
                n= 2;//Uart4_Rx % 10;
        if(GPIO_ReadInputDataBit (GPIOB ,GPIO_Pin_4) == 1)
        {
                GPIO_Write(GPIOC, num_table_1[p] );
                GPIO_Write(GPIOA, num_table_2[p] );                        
        }
        if(GPIO_ReadInputDataBit (GPIOB ,GPIO_Pin_3) == 1)
        {
                GPIO_Write(GPIOC, num_table_1[n] );
                GPIO_Write(GPIOA, num_table_2[n] );                        
        }
}

作者: 人工置頂員    時(shí)間: 2022-3-12 01:35
頂一下




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1