STM32C8T6 MODBUS_SLAVE_RTU

/*
UCOS_II
STM32F10x_FWLib V3.5.0
*/
[1]includes.h

#ifndef __INCLUDES_H__
#define __INCLUDES_H__
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>

#include "ucos_ii.h"
#include "os_cpu.h"
#include "os_cfg.h"

#include "sys.h"

#include "led.h"
#include "delay.h"
#include    "Seg_Moudle.h"
#include    "USART2_Configuration.h"
#include    "DMA1_CHANNEL_Configuration.h"
#include    "ModbusSlave.h"
#include    "key.h"
//#include    "RunMachine.h"
#include    "IIC.h"
#include    "AT24C32.h"
#include    "CRC16.h"

#endif

[2]USART2_Configuration.c

/* Includes ------------------------------------------------------------------*/
#ifndef __USART2_CONFIGURATION_H
#define __USART2_CONFIGURATION_H

#include "stdio.h"    
#include "sys.h" 
    
#define USART_REC_LEN    200      //定义最大接收字节数 200
#define EN_USART2_RX     1            //使能(1)/禁止(0)串口1接收
          
extern u8  USART2_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 ,对外使用
//extern u8  USART2_DMA_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u8 USART2_RX_COUNT;    //接收长度记录    ,对外使用

//如果想串口中断接收,请不要注释以下宏定义
void USART2_Configuration(u16 baud);
#endif

[3] USART2_Configuration.c

#include    "includes.h"

void USART2_Configuration(u16 baud)
{
// 1、定义GPIO端口、串口USART、中断NVIC初始化结构体。

//定义初始化结构体
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_Structure;
    NVIC_InitTypeDef    NVIC_InitStructure;
#ifdef VECT_TAB_RAW
        NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);//向量表存放在RAM中
#else
        NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);//向量表存放在FLASH中
#endif    

//2、打开相关外设时钟,GPIOA的时钟和引脚都在APB2总线上,USART2的时钟和引脚都在APB1总线上,所以可以直接操作,如下

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//3、给GPIO结构体成员赋值,设置引脚功能
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA.1 ModbusSlave发送接收选择
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
        
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    //择 PA.2(TXD) 和 PA.3(RXD)      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //设置复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);              //调用Init函数初始化GPIO


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;          //择 PA.2(TXD) 和 PA.3(RXD)     
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //设置模式为浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);              //调用Init函数初始化GPIO

//4、初始化GPIO端口之后我们就要配置中断分组和串口中断优先级,中断优先级分组只用设置一次。
//NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器。


//5、以上配置好之后我们就可以来配置USART了
    USART_Cmd(USART2,DISABLE);
    USART_Structure.USART_BaudRate = baud;    //设置串口波特率
    USART_Structure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;    //启用接收和传输模式
    USART_Structure.USART_Parity = USART_Parity_No;                //设置奇偶校验位
    USART_Structure.USART_StopBits = USART_StopBits_1;            //设置停止位
    USART_Structure.USART_WordLength = USART_WordLength_8b;        //设置发送或接收数据长度
    USART_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //指定是否启用硬件流控制模式
    USART_Init(USART2, &USART_Structure);                        //调用Init函数初始化USART设置
#if EN_USART2_RX          //如果使能了接收  
//Usart2 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_ITConfig(USART2, USART_IT_IDLE, ENABLE);                //使能串口接收中断标志位,当标志位为1时会触发中断
#endif    
    USART_Cmd(USART2,ENABLE);                                    //使能串口1
    USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);    //启动了DMA通道,它既可响应连到该通道上的外设的DMA请求
    USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);    //启动了DMA通道,它既可响应连到该通道上的外设的DMA请求
    USART_ClearFlag(USART2, USART_IT_IDLE);                        //清除标志位,防止误报
}

//6、最后我们不能忘记了编写口串口接收中断函数
//u8  USART2_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
u8 USART2_RX_COUNT;    //接收状态标记    
void USART2_IRQHandler(void)  //串口中断函名字,固定写法
    {
            if(USART_GetFlagStatus(USART2, USART_FLAG_IDLE)!=RESET)
            {
                USART_ReceiveData(USART2);//清除IDLE flag
                DMA_Cmd(DMA1_Channel6,DISABLE);    
                USART2_RX_COUNT=USART_REC_LEN-DMA_GetCurrDataCounter(DMA1_Channel6);
                 DMA1_CHANNEL6_USART2RX_Configuration();                
            }
    }

[4] DMA1_CHANNEL_Configuration.h
#ifndef __DMA1_CHANNEL_CONFIGURATION_H
#define __DMA1_CHANNEL_CONFIGURATION_H
#include "stdio.h"    
#include "sys.h" 
#include "stm32f10x_dma.h"

#define DEBUG_USART2_DR_BASE               (USART2_BASE + 0x04)
#define DEBUG_USART_DMA1_CLK               RCC_AHBPeriph_DMA1        
#define DEBUG_USART2_DMA1_CHANNEL6           DMA1_Channel6
#define DEBUG_USART2_DMA1_CHANNEL7           DMA1_Channel7

void DMA1_CHANNEL6_USART2RX_Configuration(void);
void DMA1_CHANNEL7_USART2TX_Configuration(u8 * buf,u16 len);
void MyDMA_Config(DMA_Channel_TypeDef* DMA_CHx,
    u32 PeripheralAddr,
u32 MemoryAddr,
u32 TranDir,
u16 BufferSize);
#endif

[5] DMA1_CHANNEL_Configuration.c
#include "includes.h"
//u8 testA[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
//#define DEBUG_USART_DMA_STREAM            DMA1_Stream7
/***************************************
*Function Name    :    DMA1_CHANNEL6_USART2RX_Configuration(void)
*Description    : 配置DMA1的通道6为USART2RX
*INPUT1            :    None
*INPUT2            :    None
*RETURN            :    conResult
***************************************/ 
u8  USART2_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
void DMA1_CHANNEL6_USART2RX_Configuration()
{
  DMA_InitTypeDef DMA_InitStructure;

    /* 开启DMA时钟*/
    RCC_AHBPeriphClockCmd(DEBUG_USART_DMA1_CLK,ENABLE);    
    DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)DEBUG_USART2_DR_BASE;
    //ModbusSlave_RX_BUF
    DMA_InitStructure.DMA_MemoryBaseAddr=(u32)USART2_RX_BUF;//
    DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;///接收传输DMA_DIR_PeripheralSRC,发送传输:DMA_DIR_PeripheralDST
    DMA_InitStructure.DMA_BufferSize = USART_REC_LEN;//设置DMA在传输时缓冲区的长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的外设递增模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置DMA的内存递增模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//设置DMA在访问时每次操作的数据长度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
//    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的优先级别:可以分为4级:VeryHigh,High,Medium,Low.
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问的
    DMA_Init(DEBUG_USART2_DMA1_CHANNEL6,&DMA_InitStructure);//统一对DMA整个模块做一次初始化,使得DMA各成员与上面的参数一致。
    DMA_Cmd(DEBUG_USART2_DMA1_CHANNEL6,ENABLE);//使能通道
}

void DMA1_CHANNEL7_USART2TX_Configuration(u8 * buf,u16 TX_BUFFER_SIZE)
{

  DMA_InitTypeDef DMA_InitStructure;
    /* 开启DMA时钟*/
    RCC_AHBPeriphClockCmd(DEBUG_USART_DMA1_CLK,ENABLE);
    DMA_Cmd(DMA1_Channel7,DISABLE);//失能通道    
    DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)DEBUG_USART2_DR_BASE;
    //ModbusSlave_RX_BUF
    DMA_InitStructure.DMA_MemoryBaseAddr=(u32)buf;//MAX64
    DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;///接收传输DMA_DIR_PeripheralSRC,发送传输:DMA_DIR_PeripheralDST
    DMA_InitStructure.DMA_BufferSize = TX_BUFFER_SIZE;//设置DMA在传输时缓冲区的长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的外设递增模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置DMA的内存递增模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//设置DMA在访问时每次操作的数据长度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
//    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的优先级别:可以分为4级:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值