-
ARM裸机串口
2017-10-23 21:12:35硬件还是tiny6410 , s3c6410, 手册上得知这款芯片...UART的使用挺简单的,和cortex-M的32差不多,先配置引脚复用为串口模式,然后设置UART的数据位,格式等,最后设置波特率。 这里配置串口0 吧,先看电路图: 串口0硬件还是tiny6410 , s3c6410, 手册上得知这款芯片有4个UART端口,可以通过中断或者DMA进行传输,速率可达3Mbps,每个UART通道有2个64字节的FIFO分别用于接受和发送。
这是它的结构图:UART的使用挺简单的,和cortex-M的32差不多,先配置引脚复用为串口模式,然后设置UART的数据位,格式等,最后设置波特率。
这里配置串口0 吧,先看电路图:串口0 是接到了GPA0 和GPA1 上面,那就直接把GPA0和GPA1配置为TXD和RXD就可以了。
GPACON &= 0x00; //将A0和A1的寄存器位置 清0 GPACOM |= 0x22; //配置他们为串口模式
这是串口0 相关的寄存器:
ULCON用来设置数据的格式,这里配置为8位,无校验,无停止位。
UCON用来配置串口的时钟选择和使用模式选择,是中断还是DMA。这里配为PCLK ,发送接受用轮询。
UFCON0 设置FIFO,UMCON0 设置自动流控制的。
UBRDIV0 和UDIVSLOT0 两个配合设置波特率,他们的关系有这么一个公式:
UBRDIV + UDIVSLOT/16 = (PCLK / (波特率 x 16)) - 1。 我们的时钟配置PCLK = 66.5Mhz ,波特率 115200,代入算得UDIVSLOT0 = 0x01,UBRDIV0 = 35;ULCON0 = 0x03; ///8位寄存器,写入全部控制字了,所以不用担心影响其他位而进行& 和 | 什么的操作。 UCON0 = 0x05; UFCON0 = 0x01; UMCON0 = 0x00; //配置波特率 UBRDIV0 = 35; UDIVSLOT0 = 0x01;
剩下几个寄存器就是实际操作UART用到的了, UFSTAT 用来判断接受缓存和发送缓存的状态,方便去读或继续发。
URXH 和UTXH 就是接受和发送寄存器。所以串口发送和接受的函数是:char getchar(void) { while((UFSTAT0 & 0x7F) ==0); return URXH0; } void putchar(char c) { while(UFSTAT0 & (1<<14)); UTXH0 = c; }
-
STM32F407的串口三驱动源码(USART3)
2020-11-07 15:43:45电路原理图 串口初始化过程 声明初始化用到的结构体 进行外部时钟初始化,此处最容易出错,详细信息可以看我上一篇博客的分析 执行GPIO初始化,设置引脚复用 执行串口初始化 使能串口 开启串口中断 进行NVIC初始化...STM32F407ZGT6的USART3驱动
STM32F407ZGT6的USART3直接通过转换芯片引出485的A,B口电路原理图
串口初始化过程
声明初始化用到的结构体
进行外部时钟初始化,此处最容易出错,详细信息可以看我上一篇博客的分析
执行GPIO初始化,设置引脚复用
执行串口初始化
使能串口
开启串口中断
进行NVIC初始化配置
初始化485的使能引脚,如果串口没有连接485转换芯片的话,不需要进行这个步骤的设置完整代码
#include "sys.h" #include "uart3.h" #include "includes.h" #define USART3_RXBUF_LEN 15 u8 UART3_RxBuffer[USART3_RXBUF_LEN]; //串口3接收缓冲区 u8 Rx_count=0; //串口3接收到的字节数 uint8_t USART3_RxBuf[USART3_RXBUF_LEN]; uint16_t USART3_RxHead = 0; uint16_t USART3_RxTail = 0; //初始化串口3,使用9600波特率,和485设备进行通信 //bound:波特率 void uart3_init(u32 bound){ //初始化结构体 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIOE_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //外部时钟初始化 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART2时钟 //GPIO初始化,USART3使用的是PB10,PB11引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //PB10,PB11引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB10,PB11 //设置引脚复用 GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3); //GPIOB10复用为USART2 GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3); //GPIOB11复用为USART2 串口初始化 USART_InitStructure.USART_BaudRate = bound;//一般设置为9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 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; // 发模式 USART_Init(USART3, &USART_InitStructure); //初始化串口 USART_Cmd(USART3, ENABLE); //使能串口 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启相关中断 //Usart3 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;//串口3中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //初始化485的使能引脚,如果没有485转换芯片可以忽略这一步 //485的使能引脚在PE4引脚位置 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //初始化GPIOE,即初始化相应GPIOE的外部时钟 GPIOE_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIOE_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIOE_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOE,&GPIOE_InitStructure); GPIO_ResetBits(GPIOE,GPIO_Pin_4); } //串口3的发送函数 void Uart3_SendStr(u8* SendBuf,u8 len) { //发送数据前将485使能引脚置位,执行485输出 GPIO_SetBits(GPIOE,GPIO_Pin_4);//LED1 while(len>0) { while((USART3->SR&0X40)==0);//等待发送完成 USART3->DR = (u8) *SendBuf; SendBuf++; len--; } while((USART3->SR&0X40)==0); //这一步绝对不能少,保证最后一个字节发送成功 //发送完成之后设置485使能引脚置位,转为接收状态 GPIO_ResetBits(GPIOE,GPIO_Pin_4); } //串口3接收中断 void USART3_IRQHandler(void) { static int flag=1; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { flag*=-1; if(flag==-1) GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_RESET); if(flag==1) GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_SET); USART3_RxBuf[USART3_RxTail++] = USART_ReceiveData(USART3); USART3_RxTail &= USART3_RXBUF_LEN-1; } }
-
46_ZYNQ7020开发板驱动AD7606逻辑分析仪分析串口显示
2020-09-22 18:45:48AD7606是一款8通道同步采样数据采集系统,片内集成输入放大器,过压保护电路,二阶模拟抗混叠滤波器、模拟多路复用器、16位200KPS SARADC和一个数字滤波器,2.5V基准电压源。 可以处理 ±10V与±5V真双极性输入信号...一、AD7606模块参数
AD型号:AD7606
通道数:8通道
AD位数:16bit
最高采样频率:200ksps
输入电压:-5V~+5V
二、模块结构
三、AD7607简介
AD7606是一款8通道同步采样数据采集系统,片内集成输入放大器,过压保护电路,二阶模拟抗混叠滤波器、模拟多路复用器、16位200KPS SARADC和一个数字滤波器,2.5V基准电压源。
可以处理 ±10V与±5V真双极性输入信号。
四、AD7606功能图
五、AD7606时序图
AD7606可以对所有8路的模拟输入通道同步采样。当两个CONVST引脚(CONVSTA和CONVSTB)连在一起的时,所有通道同步采样。此共用CONVST信息的上升沿启动对所有模拟输入通道的同步采样(V1至V8)。
BUSY信息告知用户正在进行转换,因此当施加CONVST上升沿时,BUSY变为逻辑高电平,在整个转换过程结束时变成低电平。BUSY信号下降沿用来使所有八个采样保持放大器返回跟踪模式。BUSY下降沿还表示可以从并行总线DB[15:0]读取8个通道的数据。AD7606的模拟输入信号为±5V或±10V,当**±5V输入范围时,1LSB=152.58uV**,当设置为**±10V输入范围,1LSB=305.175uV**。
ADC7606输出为二进制补码,ADC7606的LSB大小为FSR/65536,
六、接口定义
实验
一、在D:\4workspace\7020_Verilog\下新建“12_adc7606”文件
新建工程12_adc7606
选择器件型号点击完成
分别新建文件
新建如下文件并添加代码
顶层文件ad706_test.v
`timescale 1ns / 1ps // // Module Name: ad706_test // module ad706_test( input clk, //50mhz input rst_n, input [15:0] ad_data, //ad7606 采样数据 input ad_busy, //ad7606 忙标志位 input first_data, //ad7606 第一个数据标志位 output [2:0] ad_os, //ad7606 过采样倍率选择 output ad_cs, //ad7606 AD cs output ad_rd, //ad7606 AD data read output ad_reset, //ad7606 AD reset output ad_convstab, //ad7606 AD convert start input rx, output tx ); wire [15:0] ad_ch1; wire [15:0] ad_ch2; wire [15:0] ad_ch3; wire [15:0] ad_ch4; wire [15:0] ad_ch5; wire [15:0] ad_ch6; wire [15:0] ad_ch7; wire [15:0] ad_ch8; wire [19:0] ch1_dec; wire [19:0] ch2_dec; wire [19:0] ch3_dec; wire [19:0] ch4_dec; wire [19:0] ch5_dec; wire [19:0] ch6_dec; wire [19:0] ch7_dec; wire [19:0] ch8_dec; wire [7:0] ch1_sig; wire [7:0] ch2_sig; wire [7:0] ch3_sig; wire [7:0] ch4_sig; wire [7:0] ch5_sig; wire [7:0] ch6_sig; wire [7:0] ch7_sig; wire [7:0] ch8_sig; ad7606 u1( .clk (clk), .rst_n (rst_n), .ad_data (ad_data), .ad_busy (ad_busy), .first_data (first_data), .ad_os (ad_os), .ad_cs (ad_cs), .ad_rd (ad_rd), .ad_reset (ad_reset), .ad_convstab (ad_convstab), .ad_ch1 (ad_ch1), //ch1 ad data 16bit .ad_ch2 (ad_ch2), //ch2 ad data 16bit .ad_ch3 (ad_ch3), //ch3 ad data 16bit .ad_ch4 (ad_ch4), //ch4 ad data 16bit .ad_ch5 (ad_ch5), //ch5 ad data 16bit .ad_ch6 (ad_ch6), //ch6 ad data 16bit .ad_ch7 (ad_ch7), //ch7 ad data 16bit .ad_ch8 (ad_ch8) //ch8 ad data 16bit ); /**********电压转换程序***********/ volt_cal u2( .clk (clk), .ad_reset (ad_reset), .ad_ch1 (ad_ch1), //ch1 ad data 16bit (input) .ad_ch2 (ad_ch2), //ch2 ad data 16bit (input) .ad_ch3 (ad_ch3), //ch3 ad data 16bit (input) .ad_ch4 (ad_ch4), //ch4 ad data 16bit (input) .ad_ch5 (ad_ch5), //ch5 ad data 16bit (input) .ad_ch6 (ad_ch6), //ch6 ad data 16bit (input) .ad_ch7 (ad_ch7), //ch7 ad data 16bit (input) .ad_ch8 (ad_ch8), //ch8 ad data 16bit (input) .ch1_dec (ch1_dec), //ch1 ad voltage (output) .ch2_dec (ch2_dec), //ch2 ad voltage (output) .ch3_dec (ch3_dec), //ch3 ad voltage (output) .ch4_dec (ch4_dec), //ch4 ad voltage (output) .ch5_dec (ch5_dec), //ch5 ad voltage (output) .ch6_dec (ch6_dec), //ch6 ad voltage (output) .ch7_dec (ch7_dec), //ch7 ad voltage (output) .ch8_dec (ch8_dec), //ch8 ad voltage (output) .ch1_sig (ch1_sig), //ch1 ad 正负 (output) .ch2_sig (ch2_sig), //ch2 ad 正负 (output) .ch3_sig (ch3_sig), //ch3 ad 正负 (output) .ch4_sig (ch4_sig), //ch4 ad 正负 (output) .ch5_sig (ch5_sig), //ch5 ad 正负 (output) .ch6_sig (ch6_sig), //ch6 ad 正负 (output) .ch7_sig (ch7_sig), //ch7 ad 正负 (output) .ch8_sig (ch8_sig) //ch8 ad 正负 (output) ); /**********AD数据Uart串口发送程序***********/ uart u3( .clk50 (clk), .reset_n (rst_n), .ch1_dec (ch1_dec), //ad1 BCD voltage .ch2_dec (ch2_dec), //ad2 BCD voltage .ch3_dec (ch3_dec), //ad3 BCD voltage .ch4_dec (ch4_dec), //ad4 BCD voltage .ch5_dec (ch5_dec), //ad5 BCD voltage .ch6_dec (ch6_dec), //ad6 BCD voltage .ch7_dec (ch7_dec), //ad7 BCD voltage .ch8_dec (ch8_dec), //ad8 BCD voltage .ch1_sig (ch1_sig), //ch1 ad 正负 .ch2_sig (ch2_sig), //ch2 ad 正负 .ch3_sig (ch3_sig), //ch3 ad 正负 .ch4_sig (ch4_sig), //ch4 ad 正负 .ch5_sig (ch5_sig), //ch5 ad 正负 .ch6_sig (ch6_sig), //ch6 ad 正负 .ch7_sig (ch7_sig), //ch7 ad 正负 .ch8_sig (ch8_sig), //ch8 ad 正负 .tx (tx) ); //实例化ila逻辑分析仪 ila_0 ila_0_inst ( .clk (clk ), .probe0 (ad_ch1 ), .probe1 (ad_ch2 ), .probe2 (ad_data) ); endmodule
新建ad7606.v
`timescale 1ns / 1ps // // Module Name: ad7606 // module ad7606( input clk, //50mhz input rst_n, input [15:0] ad_data, //ad7606 采样数据 input ad_busy, //ad7606 忙标志位 input first_data, //ad7606 第一个数据标志位 output [2:0] ad_os, //ad7606 过采样倍率选择 output reg ad_cs, //ad7606 AD cs output reg ad_rd, //ad7606 AD data read output reg ad_reset, //ad7606 AD reset output reg ad_convstab, //ad7606 AD convert start output reg [15:0] ad_ch1, //AD第1通道的数据 output reg [15:0] ad_ch2, //AD第2通道的数据 output reg [15:0] ad_ch3, //AD第3通道的数据 output reg [15:0] ad_ch4, //AD第4通道的数据 output reg [15:0] ad_ch5, //AD第5通道的数据 output reg [15:0] ad_ch6, //AD第6通道的数据 output reg [15:0] ad_ch7, //AD第7通道的数据 output reg [15:0] ad_ch8 //AD第8通道的数据 ); reg [15:0] cnt; reg [5:0] i; reg [3:0] state; parameter IDLE=4'd0; parameter AD_CONV=4'd1; parameter Wait_1=4'd2; parameter Wait_busy=4'd3; parameter READ_CH1=4'd4; parameter READ_CH2=4'd5; parameter READ_CH3=4'd6; parameter READ_CH4=4'd7; parameter READ_CH5=4'd8; parameter READ_CH6=4'd9; parameter READ_CH7=4'd10; parameter READ_CH8=4'd11; parameter READ_DONE=4'd12; assign ad_os=3'b000; //AD 复位电路 always@(posedge clk) begin if(cnt<16'hffff) begin cnt<=cnt+1; ad_reset<=1'b1; end else ad_reset<=1'b0; end always @(posedge clk) begin if (ad_reset==1'b1) begin state<=IDLE; ad_ch1<=0; ad_ch2<=0; ad_ch3<=0; ad_ch4<=0; ad_ch5<=0; ad_ch6<=0; ad_ch7<=0; ad_ch8<=0; ad_cs<=1'b1; ad_rd<=1'b1; ad_convstab<=1'b1; i<=0; end else begin case(state) IDLE: begin ad_cs<=1'b1; ad_rd<=1'b1; ad_convstab<=1'b1; if(i==20) begin i<=0; state<=AD_CONV; end else i<=i+1'b1; end AD_CONV: begin if(i==2) begin //等待2个clock i<=0; state<=Wait_1; ad_convstab<=1'b1; end else begin i<=i+1'b1; ad_convstab<=1'b0; //启动AD转换 end end Wait_1: begin if(i==5) begin //等待5个clock, 等待busy信号为高 i<=0; state<=Wait_busy; end else i<=i+1'b1; end Wait_busy: begin if(ad_busy==1'b0) begin //等待busy信号为低 i<=0; state<=READ_CH1; end end READ_CH1: begin ad_cs<=1'b0; //cs信号有效 if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch1<=ad_data; //读CH1 state<=READ_CH2; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH2: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch2<=ad_data; //读CH2 state<=READ_CH3; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH3: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch3<=ad_data; //读CH3 state<=READ_CH4; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH4: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch4<=ad_data; //读CH4 state<=READ_CH5; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH5: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch5<=ad_data; //读CH5 state<=READ_CH6; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH6: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch6<=ad_data; //读CH6 state<=READ_CH7; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH7: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch7<=ad_data; //读CH7 state<=READ_CH8; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_CH8: begin if(i==3) begin ad_rd<=1'b1; i<=0; ad_ch8<=ad_data; //读CH8 state<=READ_DONE; end else begin ad_rd<=1'b0; i<=i+1'b1; end end READ_DONE:begin ad_rd<=1'b1; ad_cs<=1'b1; state<=IDLE; end default: state<=IDLE; endcase end end endmodule
新建bcd.v
module bcd(clk, hex, dec); input clk; input [16:0] hex; output [19:0] dec; wire [15:0] rrhex; reg [3:0] rhex[3:0]; reg [18:0] rhexd; reg [13:0] rhexc; reg [9:0] rhexb; reg [3:0] rhexa; reg [5:0] resa,resb,resc,resd; reg [3:0] rese; assign rrhex = hex[16] ? ~hex[15:0]+1'b1 : hex[15:0]; //去符号 assign dec = {rese,resd[3:0],resc[3:0],resb[3:0],resa[3:0]}; always@(posedge clk) //第一级寄存器 begin rhex[3] <= rrhex[15:12]; rhex[2] <= rrhex[11:8]; rhex[1] <= rrhex[7:4]; rhex[0] <= rrhex[3:0]; end always@(posedge clk) //高4bit译码 begin case(rhex[3]) 4'h0: rhexd <= 19'h00000; 4'h1: rhexd <= 19'h04096; //0x1000 -> 4096 (十进制) 4'h2: rhexd <= 19'h08192; //0x2000 -> 8192 (十进制) 4'h3: rhexd <= 19'h12288; //0x3000 -> 12288 (十进制) 4'h4: rhexd <= 19'h16384; //0x4000 -> 16384 (十进制) 4'h5: rhexd <= 19'h20480; //0x5000 -> 20480 (十进制) 4'h6: rhexd <= 19'h24576; //0x6000 -> 24576 (十进制) 4'h7: rhexd <= 19'h28672; //0x7000 -> 28672 (十进制) 4'h8: rhexd <= 19'h32768; //0x8000 -> 32768 (十进制) 4'h9: rhexd <= 19'h36864; //0x9000 -> 36864 (十进制) 4'ha: rhexd <= 19'h40960; //0xa000 -> 40960 (十进制) 4'hb: rhexd <= 19'h45056; //0xb000 -> 45056 (十进制) 4'hc: rhexd <= 19'h49152; //0xc000 -> 49152 (十进制) 4'hd: rhexd <= 19'h53248; //0xd000 -> 53248 (十进制) 4'he: rhexd <= 19'h57344; //0xe000 -> 57344 (十进制) 4'hf: rhexd <= 19'h61440; //0xf000 -> 61440 (十进制) default: rhexd <= 19'h00000; endcase end always@(posedge clk) //次高4bit译码 begin case(rhex[2]) 4'h0: rhexc <= 14'h0000; 4'h1: rhexc <= 14'h0256; //0x100 -> 256 (十进制) 4'h2: rhexc <= 14'h0512; //0x200 -> 512 (十进制) 4'h3: rhexc <= 14'h0768; //0x300 -> 768 (十进制) 4'h4: rhexc <= 14'h1024; //0x400 -> 1024 (十进制) 4'h5: rhexc <= 14'h1280; //0x500 -> 1280 (十进制) 4'h6: rhexc <= 14'h1536; //0x600 -> 1536 (十进制) 4'h7: rhexc <= 14'h1792; //0x700 -> 1792 (十进制) 4'h8: rhexc <= 14'h2048; //0x800 -> 2048 (十进制) 4'h9: rhexc <= 14'h2304; //0x900 -> 2304 (十进制) 4'ha: rhexc <= 14'h2560; //0xA00 -> 2560 (十进制) 4'hb: rhexc <= 14'h2816; //0xB00 -> 2816 (十进制) 4'hc: rhexc <= 14'h3072; //0xC00 -> 3072 (十进制) 4'hd: rhexc <= 14'h3328; //0xD00 -> 3328 (十进制) 4'he: rhexc <= 14'h3584; //0xE00 -> 3584 (十进制) 4'hf: rhexc <= 14'h3840; //0xF00 -> 3840 (十进制) default: rhexc <= 14'h0000; endcase end always@(posedge clk) begin case(rhex[1]) 4'h0: rhexb <= 10'h000; 4'h1: rhexb <= 10'h016; 4'h2: rhexb <= 10'h032; 4'h3: rhexb <= 10'h048; 4'h4: rhexb <= 10'h064; 4'h5: rhexb <= 10'h080; 4'h6: rhexb <= 10'h096; 4'h7: rhexb <= 10'h112; 4'h8: rhexb <= 10'h128; 4'h9: rhexb <= 10'h144; 4'ha: rhexb <= 10'h160; 4'hb: rhexb <= 10'h176; 4'hc: rhexb <= 10'h192; 4'hd: rhexb <= 10'h208; 4'he: rhexb <= 10'h224; 4'hf: rhexb <= 10'h240; default: rhexb <= 10'h000; endcase end always@(posedge clk) begin rhexa <= rhex[0]; end always@(posedge clk) //每个结果按同级单个bcd码相加,高一级的bcd码要加上低一级的进位,也就是高出4位的部分 begin resa = addbcd4(rhexa[3:0],rhexb[3:0],rhexc[3:0], rhexd[3:0]); resb = addbcd4(resa[5:4], rhexb[7:4],rhexc[7:4], rhexd[7:4]); resc = addbcd4(resb[5:4], rhexb[9:8],rhexc[11:8], rhexd[11:8]); resd = addbcd4(resc[5:4], 4'h0, rhexc[13:12],rhexd[15:12]); rese = resd[5:4] + rhexd[18:16]; end function [5:0] addbcd4; input [3:0] add1,add2,add3,add4; begin addbcd4 = add1 + add2 + add3 + add4; if(addbcd4 > 6'h1d) //>29 最低有一个可能出现0xf,但由二进制转换而来的数在这里不会出现大于40的情况 addbcd4 = addbcd4 + 5'h12; else if(addbcd4 > 5'h13) //>19对结果加12 addbcd4 = addbcd4 + 4'hc; else if(addbcd4 > 4'h9) //>9对结果加6 addbcd4 = addbcd4 + 4'h6; end endfunction endmodule
新建clkdiv.v
`timescale 1ns / 1ps // // Module Name: clkdiv // module clkdiv(clk50, clkout); input clk50; //系统时钟 output clkout; //采样时钟输出 reg clkout; reg [15:0] cnt; always @(posedge clk50) //分频进程 begin if(cnt == 16'd162) begin clkout <= 1'b1; cnt <= cnt + 16'd1; end else if(cnt == 16'd325) begin clkout <= 1'b0; cnt <= 16'd0; end else begin cnt <= cnt + 16'd1; end end endmodule
新建uart.v
`timescale 1ns / 1ps // // module uart( input clk50, //50Mhz clock input reset_n, input [19:0] ch1_dec, input [19:0] ch2_dec, input [19:0] ch3_dec, input [19:0] ch4_dec, input [19:0] ch5_dec, input [19:0] ch6_dec, input [19:0] ch7_dec, input [19:0] ch8_dec, input [7:0] ch1_sig, input [7:0] ch2_sig, input [7:0] ch3_sig, input [7:0] ch4_sig, input [7:0] ch5_sig, input [7:0] ch6_sig, input [7:0] ch7_sig, input [7:0] ch8_sig, output tx ); /********************************************/ //存储待发送的串口信息 /********************************************/ reg [7:0] uart_ad [113:0]; //存储发送的ASIC字符 always @(clk) begin //定义发送的字符 if(uart_stat==3'b000) begin uart_ad[0]<=65; //存储字符 A uart_ad[1]<=68; //存储字符 D uart_ad[2]<=49; //存储字符 1 uart_ad[3]<=58; //存储字符 : uart_ad[4]<=ch1_sig; //存储字符 正负 uart_ad[5]<=ch1_dec[19:16] + 48; //存储字符 个位 uart_ad[6]<=46; //存储字符 . uart_ad[7]<=ch1_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[8]<=ch1_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[9]<=ch1_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[10]<=ch1_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[11]<=86; //存储字符 V uart_ad[12]<=32; //存储字符 空格 uart_ad[13]<=32; //存储字符 空格 uart_ad[14]<=65; //存储字符 A uart_ad[15]<=68; //存储字符 D uart_ad[16]<=50; //存储字符 2 uart_ad[17]<=58; //存储字符 : uart_ad[18]<=ch2_sig; //存储字符 正负 uart_ad[19]<=ch2_dec[19:16] + 48; //存储字符 个位 uart_ad[20]<=46; //存储字符 . uart_ad[21]<=ch2_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[22]<=ch2_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[23]<=ch2_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[24]<=ch2_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[25]<=86; //存储字符 V uart_ad[26]<=32; //存储字符 空格 uart_ad[27]<=32; //存储字符 空格 uart_ad[28]<=65; //存储字符 A uart_ad[29]<=68; //存储字符 D uart_ad[30]<=51; //存储字符 3 uart_ad[31]<=58; //存储字符 : uart_ad[32]<=ch3_sig; //存储字符 正负 uart_ad[33]<=ch3_dec[19:16] + 48; //存储字符 个位 uart_ad[34]<=46; //存储字符 . uart_ad[35]<=ch3_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[36]<=ch3_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[37]<=ch3_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[38]<=ch3_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[39]<=86; //存储字符 V uart_ad[40]<=32; //存储字符 空格 uart_ad[41]<=32; //存储字符 空格 uart_ad[42]<=65; //存储字符 A uart_ad[43]<=68; //存储字符 D uart_ad[44]<=52; //存储字符 4 uart_ad[45]<=58; //存储字符 : uart_ad[46]<=ch4_sig; //存储字符 正负 uart_ad[47]<=ch4_dec[19:16] + 48; //存储字符 个位 uart_ad[48]<=46; //存储字符 . uart_ad[49]<=ch4_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[50]<=ch4_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[51]<=ch4_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[52]<=ch4_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[53]<=86; //存储字符 V uart_ad[54]<=32; //存储字符 空格 uart_ad[55]<=32; //存储字符 空格 uart_ad[56]<=65; //存储字符 A uart_ad[57]<=68; //存储字符 D uart_ad[58]<=53; //存储字符 5 uart_ad[59]<=58; //存储字符 : uart_ad[60]<=ch5_sig; //存储字符 正负 uart_ad[61]<=ch5_dec[19:16] + 48; //存储字符 个位 uart_ad[62]<=46; //存储字符 . uart_ad[63]<=ch5_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[64]<=ch5_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[65]<=ch5_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[66]<=ch5_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[67]<=86; //存储字符 V uart_ad[68]<=32; //存储字符 空格 uart_ad[69]<=32; //存储字符 空格 uart_ad[70]<=65; //存储字符 A uart_ad[71]<=68; //存储字符 D uart_ad[72]<=54; //存储字符 6 uart_ad[73]<=58; //存储字符 : uart_ad[74]<=ch6_sig; //存储字符 正负 uart_ad[75]<=ch6_dec[19:16] + 48; //存储字符 个位 uart_ad[76]<=46; //存储字符 . uart_ad[77]<=ch6_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[78]<=ch6_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[79]<=ch6_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[80]<=ch6_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[81]<=86; //存储字符 V uart_ad[82]<=32; //存储字符 空格 uart_ad[83]<=32; //存储字符 空格 uart_ad[84]<=65; //存储字符 A uart_ad[85]<=68; //存储字符 D uart_ad[86]<=55; //存储字符 7 uart_ad[87]<=58; //存储字符 : uart_ad[88]<=ch7_sig; //存储字符 正负 uart_ad[89]<=ch7_dec[19:16] + 48; //存储字符 个位 uart_ad[90]<=46; //存储字符 . uart_ad[91]<=ch7_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[92]<=ch7_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[93]<=ch7_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[94]<=ch7_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[95]<=86; //存储字符 V uart_ad[96]<=32; //存储字符 空格 uart_ad[97]<=32; //存储字符 空格 uart_ad[98]<=65; //存储字符 A uart_ad[99]<=68; //存储字符 D uart_ad[100]<=56; //存储字符 8 uart_ad[101]<=58; //存储字符 : uart_ad[102]<=ch8_sig; //存储字符 正负 uart_ad[103]<=ch8_dec[19:16] + 48; //存储字符 个位 uart_ad[104]<=46; //存储字符 . uart_ad[105]<=ch8_dec[15:12] + 48; //存储字符 小数点后一位 uart_ad[106]<=ch8_dec[11:8] + 48; //存储字符 小数点后二位 uart_ad[107]<=ch8_dec[7:4] + 48; //存储字符 小数点后三位 uart_ad[108]<=ch8_dec[3:0] + 48; //存储字符 小数点后四位 uart_ad[109]<=86; //存储字符 V uart_ad[110]<=32; //存储字符 空格 uart_ad[111]<=32; //存储字符 空格 uart_ad[112]<=10; //换行符 uart_ad[113]<=13; //回车符 end end /********************************************/ //串口发送时间字符串uart_ad[0]~uart_ad[113] /********************************************/ reg [15:0] uart_cnt; reg [2:0] uart_stat; reg [7:0] txdata; //串口发送字符 reg wrsig; //串口发送有效信号 reg [8:0] k; reg [15:0] Time_wait; always @(posedge clk ) begin if(!reset_n) begin uart_cnt<=0; uart_stat<=3'b000; k<=0; end else begin case(uart_stat) 3'b000: begin if (Time_wait == 16'hffff) begin //两条发送字符串之间的间隔时间 uart_stat<=3'b001; Time_wait<=0; end else begin uart_stat<=3'b000; Time_wait<=Time_wait + 1'b1; end end 3'b001: begin if (k == 113 ) begin //发送第114个字符 if(uart_cnt ==0) begin txdata <= uart_ad[113]; uart_cnt <= uart_cnt + 1'b1; wrsig <= 1'b1; end else if(uart_cnt ==254) begin//一个字节发送为168个时钟,这里等待255个时钟,保证一个数据发送完成 uart_cnt <= 0; wrsig <= 1'b0; uart_stat <= 3'b010; k <= 0; end else begin uart_cnt <= uart_cnt + 1'b1; wrsig <= 1'b0; end end else begin //发送前113个字符 if(uart_cnt ==0) begin txdata <= uart_ad[k]; uart_cnt <= uart_cnt + 1'b1; wrsig <= 1'b1; end else if(uart_cnt ==254) begin//一个字节发送为168个时钟,这里等待255个时钟,保证一个数据发送完成 uart_cnt <= 0; wrsig <= 1'b0; k <= k + 1'b1; end else begin uart_cnt <= uart_cnt + 1'b1; wrsig <= 1'b0; end end end 3'b010: begin //发送finish uart_stat <= 3'b000; end default:uart_stat <= 3'b000; endcase end end /**********产生串口时钟***********/ clkdiv u0 ( .clk50 (clk50), .clkout (clk) //串口发送时钟,波特率9600的16倍 ); /*************串口发送程序************/ uarttx u1 ( .clk (clk), .datain (txdata), .wrsig (wrsig), .idle (idle), .tx (tx) ); endmodule
新建uarttx.v
`timescale 1ns / 1ps // // Module Name: uarttx // // module uarttx(clk, datain, wrsig, idle, tx); input clk; //UART时钟 input [7:0] datain; //需要发送的数据 input wrsig; //发送命令,上升沿有效 output idle; //线路状态指示,高为线路忙,低为线路空闲 output tx; //发送数据信号 reg idle, tx; reg send; reg wrsigbuf, wrsigrise; reg presult; reg[7:0] cnt; //计数器 parameter paritymode = 1'b0; //检测发送命令是否有效 always @(posedge clk) begin wrsigbuf <= wrsig; wrsigrise <= (~wrsigbuf) & wrsig; end always @(posedge clk) begin if (wrsigrise && (~idle)) //当发送命令有效且线路为空闲时,启动新的数据发送进程 begin send <= 1'b1; end else if(cnt == 8'd168) //一帧资料发送结束 begin send <= 1'b0; end end always @(posedge clk) begin if(send == 1'b1) begin case(cnt) //产生起始位 8'd0: begin tx <= 1'b0; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd16: begin tx <= datain[0]; //发送数据0位 presult <= datain[0]^paritymode; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd32: begin tx <= datain[1]; //发送数据1位 presult <= datain[1]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd48: begin tx <= datain[2]; //发送数据2位 presult <= datain[2]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd64: begin tx <= datain[3]; //发送数据3位 presult <= datain[3]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd80: begin tx <= datain[4]; //发送数据4位 presult <= datain[4]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd96: begin tx <= datain[5]; //发送数据5位 presult <= datain[5]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd112: begin tx <= datain[6]; //发送数据6位 presult <= datain[6]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd128: begin tx <= datain[7]; //发送数据7位 presult <= datain[7]^presult; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd144: begin tx <= presult; //发送奇偶校验位 presult <= datain[0]^paritymode; idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd160: begin tx <= 1'b1; //发送停止位 idle <= 1'b1; cnt <= cnt + 8'd1; end 8'd168: begin tx <= 1'b1; idle <= 1'b0; //一帧资料发送结束 cnt <= cnt + 8'd1; end default: begin cnt <= cnt + 8'd1; end endcase end else begin tx <= 1'b1; cnt <= 8'd0; idle <= 1'b0; end end endmodule
新建volt_cal.v
`timescale 1ns / 1ps // // Module Name: volt_cal // module volt_cal( input clk, //50mhz input ad_reset, input [15:0] ad_ch1, //AD第1通道的数据 input [15:0] ad_ch2, //AD第2通道的数据 input [15:0] ad_ch3, //AD第3通道的数据 input [15:0] ad_ch4, //AD第4通道的数据 input [15:0] ad_ch5, //AD第5通道的数据 input [15:0] ad_ch6, //AD第6通道的数据 input [15:0] ad_ch7, //AD第7通道的数据 input [15:0] ad_ch8, //AD第8通道的数据 output [19:0] ch1_dec, //AD第1通道的十进制电压数据 output [19:0] ch2_dec, //AD第1通道的十进制电压数据 output [19:0] ch3_dec, //AD第1通道的十进制电压数据 output [19:0] ch4_dec, //AD第1通道的十进制电压数据 output [19:0] ch5_dec, //AD第1通道的十进制电压数据 output [19:0] ch6_dec, //AD第1通道的十进制电压数据 output [19:0] ch7_dec, //AD第1通道的十进制电压数据 output [19:0] ch8_dec, //AD第1通道的十进制电压数据 output reg [7:0] ch1_sig, //AD第1通道的数据正负字符 output reg [7:0] ch2_sig, //AD第2通道的数据正负字符 output reg [7:0] ch3_sig, //AD第1通道的数据正负字符 output reg [7:0] ch4_sig, //AD第2通道的数据正负字符 output reg [7:0] ch5_sig, //AD第1通道的数据正负字符 output reg [7:0] ch6_sig, //AD第2通道的数据正负字符 output reg [7:0] ch7_sig, //AD第1通道的数据正负字符 output reg [7:0] ch8_sig //AD第2通道的数据正负字符 ); reg [15:0] ch1_reg; reg [15:0] ch2_reg; reg [15:0] ch3_reg; reg [15:0] ch4_reg; reg [15:0] ch5_reg; reg [15:0] ch6_reg; reg [15:0] ch7_reg; reg [15:0] ch8_reg; reg [31:0] ch1_data_reg; reg [31:0] ch2_data_reg; reg [31:0] ch3_data_reg; reg [31:0] ch4_data_reg; reg [31:0] ch5_data_reg; reg [31:0] ch6_data_reg; reg [31:0] ch7_data_reg; reg [31:0] ch8_data_reg; reg [31:0] ch1_vol; reg [31:0] ch2_vol; reg [31:0] ch3_vol; reg [31:0] ch4_vol; reg [31:0] ch5_vol; reg [31:0] ch6_vol; reg [31:0] ch7_vol; reg [31:0] ch8_vol; //AD 电压换算 always @(posedge clk) begin if(ad_reset == 1'b1) begin ch1_reg<=0; ch2_reg<=0; ch3_reg<=0; ch4_reg<=0; ch5_reg<=0; ch6_reg<=0; ch7_reg<=0; ch8_reg<=0; end else begin //CH1数据/ if(ad_ch1[15]==1'b1) begin //如果是负电压 ch1_reg<=16'hffff-ad_ch1+1'b1; ch1_sig <= 45; //'-' asic码 end else begin ch1_reg<=ad_ch1; ch1_sig<=43; //'+' asic码 end //CH2数据/ if(ad_ch2[15]==1'b1) begin //如果是负电压 ch2_reg<=16'hffff-ad_ch2+1'b1; ch2_sig <= 45; //'-' asic码 end else begin ch2_reg<=ad_ch2; ch2_sig<=43; //'+' asic码 end //CH3数据/ if(ad_ch3[15]==1'b1) begin //如果是负电压 ch3_reg<=16'hffff-ad_ch3+1'b1; ch3_sig <= 45; //'-' asic码 end else begin ch3_reg<=ad_ch3; ch3_sig<=43; //'+' asic码 end //CH4数据/ if(ad_ch4[15]==1'b1) begin //如果是负电压 ch4_reg<=16'h7ffff-ad_ch4+1'b1; ch4_sig <= 45; //'-' asic码 end else begin ch4_reg<=ad_ch4; ch4_sig<=43; //'+' asic码 end //CH5数据/ if(ad_ch5[15]==1'b1) begin //如果是负电压 ch5_reg<=16'hffff-ad_ch5+1'b1; ch5_sig <= 45; //'-' asic码 end else begin ch5_reg<=ad_ch5; ch5_sig<=43; //'+' asic码 end //CH6数据/ if(ad_ch6[15]==1'b1) begin //如果是负电压 ch6_reg<=16'hffff-ad_ch6+1'b1; ch6_sig <= 45; //'-' asic码 end else begin ch6_reg<=ad_ch6; ch6_sig<=43; //'+' asic码 end //CH7数据/ if(ad_ch7[15]==1'b1) begin //如果是负电压 ch7_reg<=16'h7ffff-ad_ch7+1'b1; ch7_sig <= 45; //'-' asic码 end else begin ch7_reg<=ad_ch7; ch7_sig<=43; //'+' asic码 end //CH8数据/ if(ad_ch8[15]==1'b1) begin //如果是负电压 ch8_reg<=16'hffff-ad_ch8+1'b1; ch8_sig <= 45; //'-' asic码 end else begin ch8_reg<=ad_ch8; ch8_sig<=43; //'+' asic码 end end end //AD 电压换算(1 LSB = 5V / 32758 = 0.15mV always @(posedge clk) begin if(ad_reset == 1'b1) begin ch1_data_reg<=0; ch2_data_reg<=0; ch3_data_reg<=0; ch4_data_reg<=0; ch5_data_reg<=0; ch6_data_reg<=0; ch7_data_reg<=0; ch8_data_reg<=0; ch1_vol<=0; ch2_vol<=0; ch3_vol<=0; ch4_vol<=0; ch5_vol<=0; ch6_vol<=0; ch7_vol<=0; ch8_vol<=0; end else begin ch1_data_reg<=ch1_reg * 50000; ch2_data_reg<=ch2_reg * 50000; ch3_data_reg<=ch3_reg * 50000; ch4_data_reg<=ch4_reg * 50000; ch5_data_reg<=ch5_reg * 50000; ch6_data_reg<=ch6_reg * 50000; ch7_data_reg<=ch7_reg * 50000; ch8_data_reg<=ch8_reg * 50000; ch1_vol<=ch1_data_reg >>15; ch2_vol<=ch2_data_reg >>15; ch3_vol<=ch3_data_reg >>15; ch4_vol<=ch4_data_reg >>15; ch5_vol<=ch5_data_reg >>15; ch6_vol<=ch6_data_reg >>15; ch7_vol<=ch7_data_reg >>15; ch8_vol<=ch8_data_reg >>15; end end //16进制转化为十进制的 bcd bcd1_ist( .hex (ch1_vol[15:0]), .dec (ch1_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd2_ist( .hex (ch2_vol[15:0]), .dec (ch2_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd3_ist( .hex (ch3_vol[15:0]), .dec (ch3_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd4_ist( .hex (ch4_vol[15:0]), .dec (ch4_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd5_ist( .hex (ch5_vol[15:0]), .dec (ch5_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd6_ist( .hex (ch6_vol[15:0]), .dec (ch6_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd7_ist( .hex (ch7_vol[15:0]), .dec (ch7_dec), .clk (clk) ); //16进制转化为十进制的 bcd bcd8_ist( .hex (ch8_vol[15:0]), .dec (ch8_dec), .clk (clk) ); endmodule
添加在线逻辑分析仪
修改名字为ila_0,采用两路信号,Probes设置为2,Sample Data Depth指的是采用深度,设置的越高,采集的信号越多,同样消耗的资源也会越多。
在Probe_Ports页面,设置Probe的宽度,设置PROBEO位宽为32,用于采样timer_cnt,设置PROBE1位宽为4,用于采样地址和写入RAM的数据,点击OK,ADC的数据是16位
在ad706_test.v中添加逻辑分析仪
//实例化ila逻辑分析仪 ila_0 ila_0_inst ( .clk (clk ), .probe0 (ad_ch1 ), .probe1 (ad_ch2 ), .probe2 (ad_data) );
布局布线
查看管脚约束文件da7606.xdcset_property IOSTANDARD LVCMOS33 [get_ports {ad_data[15]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[14]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[13]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[12]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[11]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[10]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[9]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[8]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[0]}] set_property PACKAGE_PIN T12 [get_ports {ad_data[15]}] set_property PACKAGE_PIN U12 [get_ports {ad_data[14]}] set_property PACKAGE_PIN V12 [get_ports {ad_data[13]}] set_property PACKAGE_PIN W13 [get_ports {ad_data[12]}] set_property PACKAGE_PIN U13 [get_ports {ad_data[11]}] set_property PACKAGE_PIN V13 [get_ports {ad_data[10]}] set_property PACKAGE_PIN T14 [get_ports {ad_data[9]}] set_property PACKAGE_PIN T15 [get_ports {ad_data[8]}] set_property PACKAGE_PIN V17 [get_ports {ad_data[7]}] set_property PACKAGE_PIN V18 [get_ports {ad_data[6]}] set_property PACKAGE_PIN T16 [get_ports {ad_data[5]}] set_property PACKAGE_PIN U17 [get_ports {ad_data[4]}] set_property PACKAGE_PIN P15 [get_ports {ad_data[3]}] set_property PACKAGE_PIN P16 [get_ports {ad_data[2]}] set_property PACKAGE_PIN U14 [get_ports {ad_data[1]}] set_property PACKAGE_PIN U15 [get_ports {ad_data[0]}] set_property PACKAGE_PIN P14 [get_ports {ad_os[2]}] set_property PACKAGE_PIN W19 [get_ports {ad_os[1]}] set_property PACKAGE_PIN W18 [get_ports {ad_os[0]}] set_property PACKAGE_PIN W15 [get_ports ad_busy] set_property PACKAGE_PIN R14 [get_ports ad_convstab] set_property PACKAGE_PIN V15 [get_ports ad_cs] set_property PACKAGE_PIN Y17 [get_ports ad_rd] set_property PACKAGE_PIN Y16 [get_ports ad_reset] set_property PACKAGE_PIN W14 [get_ports first_data] set_property PACKAGE_PIN N15 [get_ports rst_n] set_property PACKAGE_PIN U18 [get_ports clk] set_property PACKAGE_PIN F17 [get_ports tx] set_property PACKAGE_PIN F16 [get_ports rx] set_property IOSTANDARD LVCMOS33 [get_ports {ad_os[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_os[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {ad_os[0]}] set_property IOSTANDARD LVCMOS33 [get_ports ad_busy] set_property IOSTANDARD LVCMOS33 [get_ports ad_convstab] set_property IOSTANDARD LVCMOS33 [get_ports ad_cs] set_property IOSTANDARD LVCMOS33 [get_ports ad_rd] set_property IOSTANDARD LVCMOS33 [get_ports ad_reset] set_property IOSTANDARD LVCMOS33 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports first_data] set_property IOSTANDARD LVCMOS33 [get_ports rst_n] set_property IOSTANDARD LVCMOS33 [get_ports rx] set_property IOSTANDARD LVCMOS33 [get_ports tx] create_clock -period 20.000 -name clk -waveform {0.000 10.000} [get_ports clk]
添加时序约束,点击Run synthesis 开始综合
点击“Constraints Wizard”
把"ys_clk"频率设置为50Mhz,然后点击Skip to finish结束时序约束向导
生成bitstream并下载bit文件到FPGA,通过ila观察AD7606的数据
查看的端口 -
无线物流终端的嵌入式主板的硬件设计
2020-07-23 07:35:23本设计为国家“863”项目“无线射频关键技术研究与开发”的子课题“双频RFID读写器设计”。...给出了PC/104接口信号的详细说明,并对串口复用进行了解释;给出了USB接口及CF卡接口的具体电路图,并作了分析说明。 -
C6748_RS485
2017-10-26 14:19:13使用C6748的UART1作为收发串口,输入的ttl电平信号通过ttl转485电平转换电路转为485信号,再送到485通信设备,ttl转485电平转换电路如图: 主函数如下: int main(void) { // 外设使能配置 ...使用C6748的UART1作为收发串口,输入的ttl电平信号通过ttl转485电平转换电路转为485信号,再送到485通信设备,ttl转485电平转换电路如图:
主函数如下:
intmain(void) { // 外设使能配置 PSCInit(); // GPIO 管脚复用配置 GPIOBankPinMuxSet(); // UART 初始化 UARTInit(); // 发送字符串 // 使能发送 GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH); unsignedchar i; for(i = 0; i < 34; i++) UARTCharPut(SOC_UART_1_REGS, Send[i]); // 禁用发送 GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW); // 主循环 for(;;) { Receive=UARTCharGet(SOC_UART_1_REGS); // 使能发送 GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH); UARTCharPut(SOC_UART_1_REGS, Receive); // 等待数据发送完成 for(i=0;i<200;i++); // 禁用发送 GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW); } }
先是对DSP的复用管脚进行配置,GPIOBankPinMuxSet();函数如下:
voidGPIOBankPinMuxSet(void) { // 使能 UART1 禁用流控 UARTPinMuxSetup(1, FALSE); // RS485 Enable 管脚 RS485PinMuxSetup(); }
UARTPinMuxSetup(1, FALSE);函数设置PINMUX4寄存器的PINMUX4_31_28字段为2h,PINMUX4_27_24字段为2h,使能UART1所在引脚的UART1_TX和UART1_RX功能。UARTPinMuxSetup函数如下:
voidUARTPinMuxSetup(unsignedint instanceNum, unsignedint modemCtrlChoice) { unsignedint svPinMuxRtsCts = 0; unsignedint svPinMuxTxdRxd = 0; if(0 == instanceNum) { if(TRUE == modemCtrlChoice) { svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \ ~(SYSCFG_PINMUX3_PINMUX3_27_24 | \ SYSCFG_PINMUX3_PINMUX3_31_28)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \ (PINMUX3_UART0_CTS_ENABLE | \ PINMUX3_UART0_RTS_ENABLE | \ svPinMuxRtsCts); } svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \ ~(SYSCFG_PINMUX3_PINMUX3_23_20 | \ SYSCFG_PINMUX3_PINMUX3_19_16)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \ (PINMUX3_UART0_TXD_ENABLE | \ PINMUX3_UART0_RXD_ENABLE | \ svPinMuxTxdRxd); } elseif(1 == instanceNum) { if(TRUE == modemCtrlChoice) { svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \ ~(SYSCFG_PINMUX0_PINMUX0_23_20 | \ SYSCFG_PINMUX0_PINMUX0_19_16)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \ (PINMUX0_UART1_CTS_ENABLE | \ PINMUX0_UART1_RTS_ENABLE | \ svPinMuxRtsCts); } svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \ ~(SYSCFG_PINMUX4_PINMUX4_31_28 | \ SYSCFG_PINMUX4_PINMUX4_27_24)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \ (PINMUX4_UART1_TXD_ENABLE | \ PINMUX4_UART1_RXD_ENABLE | \ svPinMuxTxdRxd); } elseif(2 == instanceNum) { if(TRUE == modemCtrlChoice) { svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \ ~(SYSCFG_PINMUX0_PINMUX0_31_28 | \ SYSCFG_PINMUX0_PINMUX0_27_24)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \ (PINMUX0_UART2_CTS_ENABLE | \ PINMUX0_UART2_RTS_ENABLE | \ svPinMuxRtsCts); } svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \ ~(SYSCFG_PINMUX4_PINMUX4_23_20 | \ SYSCFG_PINMUX4_PINMUX4_19_16)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \ (PINMUX4_UART2_TXD_ENABLE | \ PINMUX4_UART2_RXD_ENABLE | \ svPinMuxTxdRxd); } else { } }
(指南P204)
(指南P225)
(指南P225)
RS485PinMuxSetup();函数使能RS485管脚,函数如下:
voidRS485PinMuxSetup(void) { unsignedint savePinMux = 0; savePinMux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \ ~(SYSCFG_PINMUX0_PINMUX0_19_16 | \ SYSCFG_PINMUX0_PINMUX0_19_16)); HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = (PINMUX0_RS485_ENABLE | savePinMux); }
该函数设置PINMUX0寄存器的PINMUX0_19_16字段为8,将GP0[11]功能所在复用引脚的功能设为GP0[11],GP0[11]外接到ttl转485芯片(ISO3082DW)的使能引脚REn和DE,控制485芯片功能的使能和禁止。该485芯片电路的工作方式为半双工,发送时,要使能DE脚(Data Enable),GP0[11]为高;接收时,要使能REn脚(Receive enable),GP0[11]为低。
(指南P204)
(指南P218)
GPIO管脚复用配置好后,对UART初始化,初始化函数UARTInit();函数如下:
voidUARTInit(void) { // 配置 UART1 参数 // 波特率 115200 数据位 8 停止位 1 无校验位 UARTConfigSetExpClk(SOC_UART_1_REGS, UART_1_FREQ, BAUD_115200, UART_WORDL_8BITS, UART_OVER_SAMP_RATE_16); // 使能 UART1 UARTEnable(SOC_UART_1_REGS); // 设置使能管脚为输出状态 GPIO0[11] GPIODirModeSet(SOC_GPIO_0_REGS, 12, GPIO_DIR_OUTPUT); }
函数配置UART1的参数,并使能UART1,函数没有使能UART1的接收和发送FIFO,所以每次收发都是一个字节。然后,设置485芯片使能引脚GP0[11]为输出状态。GPIODirModeSet函数如下:
voidGPIODirModeSet(unsignedint baseAdd, unsignedint pinNumber, unsignedint pinDir) { unsignedint regNumber = 0; unsignedint pinOffset = 0; /* ** Each register contains settings for each pin of two banks. The 32 bits ** represent 16 pins each from the banks. Thus the register number must be ** calculated based on 32 pins boundary. */ regNumber = (pinNumber - 1)/32; /* ** In every register the least significant bits starts with a GPIO number on ** a boundary of 32. Thus the pin offset must be calculated based on 32 ** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in ** 'register_name01'. */ pinOffset = (pinNumber - 1) % 32; if(GPIO_DIR_OUTPUT == pinDir) { HWREG(baseAdd + GPIO_DIR(regNumber)) &= ~(1 << pinOffset); } else { HWREG(baseAdd + GPIO_DIR(regNumber)) |= (1 << pinOffset); } }
(手册P254)
(指南P846)
(指南P849)
完成UART1的初始化之后,就完成了所有的初始化工作了。这时,要发送数据到上位机的话,需要先使能485芯片,所以主函数先设置GP0[11]的输出电平为高,
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH);。函数如下:
voidGPIOPinWrite(unsignedint baseAdd, unsignedint pinNumber, unsignedint bitValue) { unsignedintregNumber = 0; unsignedint pinOffset = 0; /* ** Each register contains settings for each pin of two banks. The 32 bits ** represent 16 pins each from the banks. Thus the register number must be ** calculated based on 32 pins boundary. */ regNumber = (pinNumber - 1)/32; /* ** In every register the least significant bits starts with a GPIO number on ** a boundary of 32. Thus the pin offset must be calculated based on 32 ** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in ** 'register_name01'. */ pinOffset = (pinNumber - 1) % 32; if(GPIO_PIN_LOW == bitValue) { HWREG(baseAdd + GPIO_CLR_DATA(regNumber)) = (1 << pinOffset); } elseif(GPIO_PIN_HIGH == bitValue) { HWREG(baseAdd + GPIO_SET_DATA(regNumber)) = (1 << pinOffset); } }
设置GP0[11]脚的输出为高,需要设置SET_DATA01寄存器的11位为1.
(指南P846)
(指南P853)
使能了485芯片的数据发送功能后,就可以往UART1写数据了。UARTCharPut(SOC_UART_1_REGS, Send[i]);将定义好的数据写往UART1的THR(transmitter holding register,THR)。然后禁用485芯片的发送功能,将GP0[11]清0,GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW);。这时,485芯片处于接收状态,UART1等待上位机发送数据过来,Receive=UARTCharGet(SOC_UART_1_REGS);。收到数据后,再次启用发送功能,将收到的数据原封不动地发回去。
-
工业电子中的基于AVR微控制器的ADC按键设计技巧
2020-12-13 08:44:50通常实现键盘接口的方式有:直接输入、矩阵结构、A/D方式、键盘和显示复用、并行扩展、串口扩充以及用键盘和显示专用控制器件。本设计使用A/D转换的方法,其硬件电路简单,按键电路与MCU的连线少,易修改,而且可以节省... -
基于AVR微控制器的ADC按键设计技巧
2021-02-03 17:22:58通常实现键盘接口的方式有:直接输入、矩阵结构、A/D方式、键盘和显示复用、并行扩展、串口扩充以及用键盘和显示专用控制器件。本设计使用A/D转换的方法,其硬件电路简单,按键电路与MCU的连线少,易修改,而且可以节省... -
Router_Switchboard Configuration<15>
2013-09-23 15:36:18实验设备:路由器(带串口) 4台V.35线缆(DTE/DCE) 3条实验原理:帧中继的标准可以为帧中继网络中可配置和管理的永久虚电路(PVC)进行编址,帧中继永久虚电路由数据链路连接标识符(DLCI)来标识。当帧中继为多个... -
FM1208 CPU卡操作程序调试小结
2011-10-21 19:02:09所以在硬件电路搭建好了之后,首先要做的是调试SPI接口。我们所用的控制芯片是STM32F103C8TL,其中集成了SPI接口,对其进行操作就是进行一些设置,然后读写缓冲区,标志位,片选信号线。在程序中设置如下: SCK,... -
51基础知识学习笔记
2020-10-31 13:35:51内置12M的时钟电路(注:需要一个外部晶振驱动) 2、8051的总线 8051具有8位数据总线,16位的地址总线,地址总线和数据总线是复用的。再用哈佛结构,程序存储器和数据存储器的地址空间各自独立。具有0~8K的程序... -
Router Configuration<14>
2013-09-04 16:17:55帧中继基本配置:Target: 帧中继基本配置实验设备:路由器(带串口) 2台V.35线缆(DTE/DCE) 1对实验原理:帧中继的标准可以为帧中继网络中可配置和管理的永久虚电路(PVC)进行编址,帧中继永久虚电路由数据链路连接... -
论文研究-在线社会网络演化模型.pdf
2019-09-12 12:29:21四路信号数据采样通过四片A/D转换器(ADC083000)完成,采样结果传输到Xilinx公司新一代现场可编程门阵列(FPGA)-Virtex5芯片作数据的多路复用和相关运算,相关结果通过串口上传到计算机。详细介绍了系统结构、数据... -
STM32点亮LED寄存器版
2019-11-21 21:06:38寄存器点亮LED 在库函数盛行的今天,不知道...用户可以通过编程灵活的对接口进行控制,实现对电路板上LED、数码管、按键等常用设备控制驱动,也可以作为串口的数据收发管脚,或AD的接口等复用功能使用。因此其作用和... -
电子设计.doc
2019-05-28 11:58:280132、单片机-485-PC串口通信proteus仿真+程序资料 0133、单片机 交通灯设计论文资料 0134、单片机串行口与PC机通讯资料 0135、单片机串行通信发射机论文资料 0136、单片机定时闹钟论文资料 0137、单片机红外遥控... -
这几天的单片机红外通信
2019-07-12 22:38:57红外通信也是单片机接口中的一种,类似于串口通信,当然是有不同,但是我想如果了解了大多数通信方式之后,会感觉其实都是那个样子的,只是有了统一的标准,加快了开发的速度和提高了兼容和复用性. 情况是这个样子的,我想... -
【可见光室内定位】(二)基于光电器件PD的可见光室内定位技术
2021-01-24 15:37:12编码方案1️⃣ 基于UART串口通信的通信协议2️⃣ 基于脉宽调制的通信协议2. 调制方案1️⃣ PWM调制技术2️⃣ OOK调制技术3. 信道通信时序方案1️⃣ 数字时分复用(TDM)???? 接收端4. 滤波方案5. 解调方案6. 降噪... -
基于RC7235的多种V.35接口转换和光纤MODEM方案
2020-12-04 15:48:27本文讨论的ASIC芯片RC7235集成度较高,带有丰富的接口,只需简单的外围电路,即可灵活构成多种应用方案,如实现V.35光纤MODEM和E1转换器等TDM数据复用设备。 V.35是同步的串行数据接口,具有高可靠的连接性,... -
基于AT89S52 单片的频率计
2010-01-04 08:47:37集成电路的类型很多,从大的方面可以分为模拟电路和数字集成电路2 大 类。数字集成电路广泛用于计算机、控制与测量系统,以及其它电子设备中。 一般说来,数字系统中运行的电信号,其大小往往并不改变,但在实践分布... -
无线通信技术----蓝牙,无线通信技术----蓝牙
2011-06-23 00:42:428) 串口仿真协议(RFCOMM)是一种简单传输协议,可在L2CAP之上仿真RS-232(EIATIA-232-E)串口电路,因此它实际上是一种电缆替代协议。RFCOMM协议支持两台蓝牙设备之间的多达60个并发连接。 9) TCP(传输控制协议... -
c语言编写单片机技巧
2009-04-19 12:15:17要实现单片机与电脑的连接,最简单的方式就是采用串口通讯,但需要加一颗RS-232芯片。 17. 在ARM编程中又应当如何? 答:就以嵌入式系统观念为例,一般嵌入式处理器可以分为三类:嵌入式微处理器、嵌入式微... -
单片机C语言程序设计实训100例--基于AVR+PROTEUS仿真(源程序)
2011-07-13 13:58:362.2 仿真电路原理图设计 2.3 元件选择 2.4 仿真运行 2.5 PROTEUS与AVR Studio的联合调试 2.6 PROTEUS在AVR单片机应用系统开发中的优势 第三章:基础程序设计 3.1 闪烁的LED 3.2 左右来回的流水灯 3.3 花样...
-
C#坦克大战带技能版源码(RealTank).zip
-
MySQL 事务和锁
-
ACID (数据库事务正确执行的四个基本要素的缩写)
-
协程的意义
-
vue cli相关问题
-
Tribological-behaviour-and-wear-mechanism-of-MoS2-Cr-coat_2003_Tribology-Int.pdf
-
C++ STL(十二):常用遍历算法(for_each、transform)
-
MyBatisSelf.rar
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
golang 判断文件(或目录)是否存在 练习
-
Unity RUST 逆向安全开发
-
MySQL 数据库权限管理(用户高级管理和精确访问控制)
-
智慧路灯杆云盒网关的功能和应用
-
基于Qt的LibVLC开发教程
-
2019年-华启学院中级通信工程师综合能力真题及答案(完整版).pdf
-
MySQL 高可用(DRBD + heartbeat)
-
第 229 场周赛记录(460 / 3483 )
-
mysql-8.0.21-winx64.zip
-
中文分词词典UserDict.txt
-
用微服务spring cloud架构打造物联网云平台