Experimental Manuals FPGA Tutor Risc-V

Altera Risc-V FPGA Tutorial :AD,DA Experiment – FII-PRA040 FPGA Board Experimental 12

Experiment 12 AD,DA Experiment

12.1 Experiment Objective

Since in the real world, all naturally occurring signals are analog signals, and all that are read and processed in actual engineering are digital signals. There is a process of mutual conversion between natural and industrial signals (digital-to-analog conversion: DAC, analog-to-digital conversion: ADC). The purpose of this experiment is as follows:

  1. Learn about the theory of AD conversion
  2. Review the knowledge of the IIC protocol learned in the previous experiment and write the data into PCF8591 on the development board.
  3. Read the value of AD acquisition from PCF8591, and convert the value obtained into actual value, display it with segment display

12.2 Experiment Implement

  1. The ADC port of the chip is used for analog-to-digital conversion. The chip is correctly configured. Three variable (potentiometer, photoresistor, thermistor) voltages on the development board are collected, and the collected voltage value is displayed through the segment display.
  2. Board downloading verification, compared with resistance characteristics, verify the correctness of the results

12.3 Experiment


Introduction to AD Conversion Chip PCF8591


The PCF8591 is a monolithically integrated, individually powered, low power consuming, 8-bit CMOS data acquisition device. The PCF8591 has four analog inputs, one analog output, and one serial IIC bus interface. The three address pins A0, A1 and A2 of the PCF8591 can be used for hardware address programming. The address, control signals and data signals of the input and output on the PCF8591 device are transmitted serially via the two-wire bidirectional IIC bus.

Please refer to the previous experiment 11 for the contents of the IIC bus protocol. After the device address information and the read/write control word are sent, the control word information is sent.

PCF8591 address
PCF8591 address

Figure 12.1 PCF8591 address

The specific control word information is shown in Figure 12.1. Digit 1 – digit 0 is used for four channel settings, digit 2 is for automatic gain selection, ‘1’ is valid. Digit 5 – digit 4 determines analog input selection. Digit 6 is analog output enable. Digit 7 and digit 3 are reserved to be ‘0’. The second byte sent to PCF8951 is stored in the control register to control the device functionality. The upper nibble of the control register is used to allow the analog output to be programmed as a single-ended or differential input. The lower nibble selects an analog input channel defined by the high nibble. If the auto increment flag is set to 1, the channel number will be automatically incremented after each A/D conversion.

In this experiment, the input channel is selected as the AD acquisition input channel by using the DIP switch (SW1, SW0). The specific channel information is shown in Table 12.1. The control information is configured as 8’h40, which is the analog output, and defaults to “00” channels, which means that the photoresistor voltage value is displayed by default.

Table 12.1 Channel information

SW1，SW0 Channel Selection Acquisition Object
00 0 Voltage of photoresistor
01 1 Voltage of thermistor
10 2 Voltage of potentiometer

Hardware Design

Figure 12.2 Schematics of the AD/DA converter

。The schematics of AD/DA conversion using PCF8591 is shown in Figure 12.2. The IIC bus goes through two pull-up resistors and pulls high when not working. A0, A1, A2 are grounded, so the device address is 7’b1010000, the analog input channel AIN0 is connected to the photoresistor, AIN1 is connected to the thermistor, and AIN3 is connected to the potentiometer. When the channel is selected, FPGA will read the value in PCF8591 through the data bus ADDA_I2C_SLC for processing.

Introduction to the Program

This experiment also uses the IIC bus to control the PCF8951 chip, so the program is basically the same as Experiment 11. Only parts difference from Experiemnt 11 are indicated here.

reg [7:0] read_data_temp [15:0];

reg [11:0] dis_data_temp;

always @ (posedge clk)

dis_data_temp <= read_data_temp[0] + read_data_temp[1] + read_data_temp[2]

+ read_data_temp[3] + read_data_temp[4] + read_data_temp[5]

+ read_data_temp[6] + read_data_temp[7] + read_data_temp[8]

+ read_data_temp[9] + read_data_temp[10] + read_data_temp[11]

+ read_data_temp[12] + read_data_temp[13] + read_data_temp[14]

+ read_data_temp[15];

always @ (posedge clk )

dis_data <= dis_data_temp >> 4;

integer i;

always @ (posedge clk or negedge rst_n)


if (!rst_n) begin


read_data_temp[i] <= 8’h00;


else if (iic_done) begin

for (i=0;i<15;i=i+1)

read_data_temp[i+1] <= read_data_temp[i];

read_data_temp[0] <= read_data ;


else begin


read_data_temp[i] <= read_data_temp[i];




The role of this part is that when the chip continuously collects the voltage value across the resistor, due to a series of unstable factors, the voltage value will be unstable, so the output value will have a large error, so 16 sets of data is collected each time, then gets averaged, and the result is output as the voltage value across the resistor at this time.

Then, by the change of the voltage value, it is possible to judge the regular pattern. Such as photoresistor, the greater the light intensity, the smaller the voltage value, the smaller the resistance value, satisfying the photoresistor characteristics; the higher the thermistor temperature, the smaller the voltage value, the smaller the resistance, satisfying the photoresistor characteristics; the potentiometer rotates clockwise, and the voltage increases, the resistance increases; counterclockwise rotating decrases the voltage, and the resistance decreases.

The maximum output of the AD chip is an 8-bit digital quantity, but in fact it is not the required voltage value. It quantifies the voltage value of the range into 256 portions (8-bit binary number can represent 256 decimal numbers), so further calculations and conversions needs to be applide when displaying on the segment display.


parameter V_REF = 12’d3300;

reg [19:0] num_t;

reg [19:0] num1;

wire [3:0] data0;

wire [3:0] data1;

wire [3:0] data2;

wire [3:0] data3;

wire [3:0] data4;

wire [3:0] data5;

assign data5 = num1 / 17’d100000;

assign data4 = num1 / 14’d10000 % 4’d10;

assign data3 = num1 / 10’d1000 % 4’d10 ;

assign data2 = num1 / 7’d100 % 4’d10 ;

assign data1 = num1 / 4’d10 % 4’d10 ;

assign data0 = num1 % 4’d10;


always @ (posedge clk)

num_t <= V_REF * dis_data;

always @(posedge clk or negedge rst_n)


if (!rst_n) begin

num1 <= 20’d0;



num1 <= num_t >> 4’d8;


VCC is 3.3V, so the maximum resistance voltage is 3.3V. The 8-bit data dis_data is multiplied by 3300 and assigned to numt by 1000 times, which is convenient for display and observation. The numt is further reduced by 256 times (left shifting 8 bits) to num1, corresponding to 256 quantitized portions of PCF8951. num1 at this time is 1000 times the voltage value of two ends of the resistor. Display each digit on the segment display, in the order of high to low (data5 to data0) and add the decimal point (data3) to digit of thousands . At this time, the value displayed by the segment display is the voltage across the resistor value, and correct to 3 decimal places.

12.4 Experiment Verification


The first step: assign the pin

Table 12.2 AD conversion experiment pin mapping

Signal Name Network Label FPGA Pin Port Description
clk CLK_50M G21 System clock 50 MHz
rst_n PB3 Y6 Reset
sm_db[0] SEG_PA B15 Segment a
sm_db [1] SEG_PB E14 Segment b
sm_db [2] SEG_PC D15 Segment c
sm_db [3] SEG_PD C15 Segment d
sm_db [4] SEG_PE F13 Segment e
sm_db [5] SEG_PF E11 Segment f
sm_db [6] SEG_PG B16 Segment g
sm_db [7] SEG_DP A16 Segment h
sel[0] SEG_3V3_D0 F14 Bit selection 0
sel[1] SEG_3V3_D1 D19 Bit selection 1
sel[2] SEG_3V3_D2 E15 Bit selection 2
sel[3] SEG_3V3_D3 E13 Bit selection 3
sel[4] SEG_3V3_D4 F11 Bit selection 4
sel[5] SEG_3V3_D5 R12 Bit selection 5
data[0] SW0 U11 Swicth input
data[1] SW1 V11 Swicth input
data[2] SW2 U10 Swicth input
data[3] SW3 V10 Swicth input
data[4] SW4 V9 Swicth input
data[5] SW5 W8 Swicth input
data[6] SW6 Y8 Swicth input
data[7] SW7 W6 Swicth input
scl ADDA_I2C_SCL C20 PCF8591 clock line
sda ADDA_I2C_SDA D20 PCF8591 data line


Step 2: board verification

After the pin assignment is completed, the compilation is performed, and board downloading is verified after passing.

Under the default state, that is, the channel selection is “00”, the segment display shows the current ambient brightness state, the voltage value across the photoresistor is 2.010V, as shown in Figure 12.3.

Figure 12.3 Photoresist test phenomenon

When the channel selection is “01”, the segment display shows the current ambient temperature, the voltage across the thermistor is 2.926V, as shown in Figure 12.4.

Figure 12.4 Thermistor experiment phenomenon

When the channel is selected as “10”, the segment display shows the current resistance value, and the voltage across the potentiometer is 1.456 V, as shown in Figure 12.5.

Figure 12.5 Potentiometer experiment phenomenon

Related posts

Leave a Comment