UART_SEND详细设计方案

1.      UART_SEND简介:

串口是用的非常多的一种接口,实现原理比较简单,基本所有CPU芯片都配置有串口,所以经常被用来作为调试接口。

2.      UART_SEND规格:

实现9600波特率的串口发送,上位机串口软件可以接收到发送的数据。

 

3.      实现原理

以波特率9600为例子说明,波特率9600接收一个bit的时间为1s/9600=104us,即每隔104us发送一个数据。

 

104us = 104000ns 50M时钟的一个周期时间为20ns要远小于104000ns,所以可以用50M时钟产生的计数器来计数,然后根据计数器来发送数据。

 

新建一个计数器,50Mhz为时钟,那么计数器变化一次时间为20ns。

由于一次完整数据接收需要有1144000ns时间,所以计数器必须记到1144000ns时间。

1144000ns/20ns = 57200,所以需要16位计数器。

 

Startbit(0)占据计数器的0   -104000ns/20ns = 5200

D0           占据计数器的5200-208000ns/20ns = 10400

D1           占据计数器的10400-312000ns/20ns = 15600

D2           占据计数器的15600-416000ns/20ns = 20800

D3           占据计数器的20800-520000ns/20ns = 26000

D4           占据计数器的26000-624000ns/20ns = 31200

D5           占据计数器的31200-728000ns/20ns = 36400

D6           占据计数器的36400-832000ns/20ns = 41600

D7           占据计数器的41600-936000ns/20ns = 46800 

校验位       占据计数器的46800-1040000ns/20ns = 52000

Endbit(1)  占据计数器的52000-1144000ns/20ns = 57200

4.      Verilog HDL源代码

Verilog HDL代码为:

 

moduleUartSend (

              //input

              sys_clk        ,

              sys_rst_n      ,

              data_in        ,             //data in 8bit

 

              //output

              uart_txd

              );

 

//inputports

 

input                    sys_clk             ;    //system clock;

input                    sys_rst_n           ;   //system reset, low is active;

input[WIDTH-1:0]        data_in             ;    //to send data  8bit ;   

 

//outputports

output                   uart_txd            ;   //uart txd output ;  

 

//regdefine

reg    [WIDTH-1:0]       buff                ;        

reg    [WIDTH-1:0]       data_out            ;

 

reg                      uart_txd            ;   

reg                      txd                 ;    //temp txd signal;

    

reg  [SIZE-1:0]          counter             ;    

    

//wiredefine

 

//parameterdefine

parameterWIDTH = 8;

parameterSIZE  = 16;

 

/*******************************************************************************************************

**                              Main Program   

** 

********************************************************************************************************/

always@(posedge sys_clk or negedge sys_rst_n) begin

        if (sys_rst_n ==1'b0) begin

            buff <= 8'b0;

        end

        else

            buff  <= data_in ;

end

       

always@(posedge sys_clk or negedge sys_rst_n) begin

        if (sys_rst_n ==1'b0) begin

            counter <= 16'b0;

        end

        else if (counter > 57200 )    

            counter <= 16'b0;

        else

            counter  <= counter + 1'b1;

end

 

always@(*) begin

    if ((counter > 0)         &&  (counter <= 5200 ))  

       txd =  1'b0  ;                       

    else if ((counter > 5200)&&  (counter  <= 10400))  

       txd =  buff[0]  ;                    

    else if ((counter > 10400) &&(counter  <= 15600))  

       txd =  buff[1]  ;                    

    else if ((counter > 15600) &&(counter  <= 20800))  

       txd =  buff[2]  ;                     

    else if ((counter > 20800) &&(counter  <= 26000))  

       txd =  buff[3]  ;                    

    else if ((counter > 26000) &&(counter  <= 31200))  

       txd =  buff[4]  ;                    

    else if ((counter > 31200) &&(counter  <= 36400))  

       txd =  buff[5]  ;                    

    else if ((counter > 36400) &&(counter  <= 41600))  

       txd =  buff[6]  ;                    

    else if ((counter > 41600) &&(counter  <= 46800))  

       txd =  buff[7]  ;                    

    else if ((counter > 46800) &&(counter  <= 52000))  

       txd =  1'b1     ;                    

    else if ((counter > 52000) &&(counter  <= 57200))

       txd =  1'b1     ;       

    else           

       txd =  1'b1  ; 

end       

 

 

always@(posedge sys_clk or negedge sys_rst_n) begin

        if (sys_rst_n ==1'b0) begin

           uart_txd <= 1'b1;       

        end

        else 

           uart_txd  <= txd;       

          

end

 

endmodule

//endof RTL code     

好的,以下是使用Keil编写STMC8T6控制器与DS18B20模块的代码示例。这个代码示例使用1-Wire协议与DS18B20通信,并将读取到的温度值通过串口发送出来。 ```c #include <stdio.h> #include <stdlib.h> #include <intrins.h> #include <string.h> // 定义控制器引脚 #define OW_DQ P3_7 // 定义DS18B20命令 #define CMD_CONVERT_T 0x44 #define CMD_READ_SCRATCHPAD 0xBE // 定义串口参数 #define BAUDRATE 9600 #define UART_TX P1_1 // 定义延时函数 void DelayUs(unsigned int us) { unsigned char i; for(i = 0; i < us; i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } // 定义1-Wire总线操作函数 void OW_Reset(void) { OW_DQ = 1; DelayUs(5); OW_DQ = 0; DelayUs(500); OW_DQ = 1; DelayUs(60); } unsigned char OW_ReadBit(void) { unsigned char bit_data = 0; OW_DQ = 1; DelayUs(2); OW_DQ = 0; DelayUs(5); OW_DQ = 1; DelayUs(5); bit_data = OW_DQ; DelayUs(50); return bit_data; } void OW_WriteBit(unsigned char bit_data) { OW_DQ = 1; DelayUs(5); OW_DQ = 0; DelayUs(5); OW_DQ = bit_data; DelayUs(60); OW_DQ = 1; DelayUs(5); } void OW_WriteByte(unsigned char byte_data) { unsigned char i; for(i = 0; i < 8; i++) { OW_WriteBit(byte_data & 0x01); byte_data >>= 1; } } unsigned char OW_ReadByte(void) { unsigned char i; unsigned char byte_data = 0; for(i = 0; i < 8; i++) { byte_data >>= 1; if(OW_ReadBit()) { byte_data |= 0x80; } } return byte_data; } // 定义DS18B20读取函数 float DS18B20_ReadTemperature(void) { unsigned char i; unsigned char temp[2]; float temperature; OW_Reset(); OW_WriteByte(CMD_CONVERT_T); DelayUs(750); OW_Reset(); OW_WriteByte(CMD_READ_SCRATCHPAD); for(i = 0; i < 2; i++) { temp[i] = OW_ReadByte(); } temperature = (float)(temp[1] << 8 | temp[0]) / 16.0; return temperature; } // 定义串口发送函数 void UART_SendByte(unsigned char dat) { unsigned char i; for(i = 0; i < 8; i++) { if(dat & 0x01) { UART_TX = 1; } else { UART_TX = 0; } dat >>= 1; DelayUs(100); } } void UART_SendString(char *str) { unsigned char i; for(i = 0; i < strlen(str); i++) { UART_SendByte(str[i]); } } // 主函数 void main() { float temperature; char temp_str[10]; // 初始化串口 TMOD = 0x20; TH1 = 256 - FOSC / 32 / BAUDRATE; TL1 = TH1; TR1 = 1; SM0 = 0; SM1 = 1; REN = 1; while(1) { temperature = DS18B20_ReadTemperature(); sprintf(temp_str, "%.2f", temperature); UART_SendString(temp_str); UART_SendString("\r\n"); DelayUs(1000000); } } ``` 这个代码示例分为三个部分: 1. 1-Wire总线操作函数,用于与DS18B20进行通信。 2. DS18B20读取函数,用于读取DS18B20的温度值。 3. 串口发送函数,用于将温度值发送到PC端。 在主函数中,我们先初始化串口,然后不断读取DS18B20的温度值,并将其发送到PC端。需要注意的是,这个代码示例中并没有加入控制逻辑,你需要根据你的具体应用场景,加入相应的控制指令和判断语句。 你可以将这个代码示例复制到Keil中,进行编译和调试。需要注意的是,在实际应用中,还需要考虑到硬件连接和软件优化等问题,以确保系统的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值