NUVOTON CHIP

Published: 24/01/2024 04:02 PM

Nuvoton-N76E003

The article was written by MEIGROUP engineers

Project using Nuvoton-N76E003 8051 and library TM1637 Display, I2C EEPROM AT24Cx 24LCx , pinMode like arduino, Modbus send data emulator....

Datasheet N76E003AT20

Download package KeilC or IAR for N76E003 or this Repo

Use charging circuit VNpro for 89S&AVR as instructed USB VNpro in KeilC to load the program in Keil-C

Or USB VNpro in ISP Prog v6 to load hex file.

 

Instructions and sample program

__ Standard library __ (Standard libraries)

Standard libraries are called in all projects

#include "N76E003.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "Common.h"
#include "Delay.h"

__ Data type 8051 __ (data type)

- In addition to common data types, KeilC-8051 also has a number of other data types and memory organizations

bit var;                        // size: 1 bit - similar to bool, only has 2 values 0 and 1
xdata dataType var;     // 'xdata' - is a keyword used to specify that the variable should be stored
 // in peripheral memory instead of being stored in main memory.
 // Helps free up main memory for important tasks
                        
bit var1bit;
xdata int varInt;
xdata float varFloat;

__ Some default command __ (some default commands)

GPIO

  • GPIO mode
P04_PushPull_Mode;                  // Set gpio P04 chế độ Push-pull    - Output low-high
P11_Quasi_Mode;                     // Set gpio P11 chế độ Quasi        - Output low-high, input
P05_Input_Mode;                     // Set gpio P05 chế độ Input        - Input
P12_OpenDrain_Mode;                 // Set gpio P12 chế độ Open-Drain   - Output low, input
  • GPIO set
P04 = 1                             // Set gpio P04 lên cao (mức 1)
P11 = 0                             // Set gpio P04 mức thấp 
  • GPIO read status
value = P05;                        // Đọc giá trị input ở gpio P05 (low - high)

UART

InitialUART0_Timer3(9600);          // khởi tạo uart 0 cho timer3 với tốc độ baud là 9600
InitialUART1_Timer3(baudRate);      // Khởi tạo uart 1 cho timer3
Send_Data_To_UART0(byteData);       // Gửi 1 byte qua uart
TI = 1;                             // Sử dụng khi muốn dùng hàm `printf()`
printf("Hello world");              // Sử dụng như hàm printf trong C, gửi dữ liệu qua Serial

 

  • Example UART
//  -------------------------------- UART0 ---------------------------
void main (void) 
{
	uint8_t c;
	InitialUART0_Timer3(9600);      // 9600, 115200 - oke
	TI = 1;                         // Important, use prinft function must set TI=1;
	
	while(1)
	{
		if (RI == 1) {              // Serial.available()
			RI = 0;                 // clear available
			c = SBUF;               // Serial.read()
			Send_Data_To_UART0(c);  //Serial.write()
		}
	}
}

void main (void) 
{
	InitialUART0_Timer3(9600);      // 9600, 115200 - oke
	TI = 1;                         // Important, use prinft function must set TI=1;
	
	while(1)
	{
        printf("Hello world !!!");
	}
}

//  -------------------------------- UART1 ---------------------------

/* Tương tự, nhưng thay các từ khóa UART0, TI, RI, SBUF -> UART1, TI_1, RI_1, SBUF_1 */

Timer delay __ Built-in delay functions

Timer0_Delay100us(u32CNT);
Timer0_Delay1ms(u32CNT);
Timer1_Delay10ms(u32CNT);
Timer2_Delay500us(u32CNT);
Timer3_Delay100ms(u32CNT);
Timer0_Delay40ms(u32CNT);
Timer3_Delay10us(u32CNT);

__ USE Library __ (use self-created library)

Download folder LIB, save to package folder.

Open project in keilC, go to Options for Target -> tab C51, add "..\..\LIB" to Include Paths

_ GPIO Setup _ (using self-made "GPIO.h" library)

USE library LIB\GPIO.h __ Use GPIO.h library

    #include "GPIO.h"
  • Config gpio P12 output, P04 input, P05 Open drain mode:
pinMode(12, OUTPUT);
pinMode(4,  INPUT);
pinMode(4,  INPUT_OD);
 

Mode

Description

QUASI

Config gpio quasi mode __ (set gpio as input and output, output high-low logic level, receive input signal)

OUTPUT

Config gpio push-pull mode __ (output logic high-low)

INPUT

Config gpio input only mode __ (as input only)

INPUT_OD

Config gpio input Open-drain mode __ (output low level logic and receive input signal)

_ digital-Write-Read (LIB\GPIO.h) _ read and write digital signals

  • Set output gpio P15 to HIGH, gpio P05 to LOW
digitalWrite(15, HIGH);
digitalWrite(5, LOW);
  • Reads the value from digital pin P11, P03
digitalRead(11);
digitalRead(3);

 

_ analogRead (LIB\GPIO.h) _ reads the ADC gpio signal

  • N76E003 has 8 gpios that can read ADC signals as gpio pins AINx (x = 0 -> 7)

  • Read analog value from gpio P11

pinMode(11, INPUT);

while(1) {
    uint16_t adaValue = analogRead(11);
}

Create 2 functions Serial.read() and Serial.available() like arduino

bit serial_available() {
	return RI;
}

uint8_t serial_read() {
	RI = 0;
	return SBUF;
}

void main (void) 
{
	InitialUART0_Timer3(9600);  // 9600, 115200 - oke
	TI = 1;                     // Important, use prinft function must set TI=1;
	
	while(1)
	{
		if (serial_available() == 1) {
			uint8_t c = serial_read();
			Send_Data_To_UART0(c);
		}
	}
}

set up Timer2 interrupt __ creates Timer2 interrupt 1kHz (used as millis() on arduino)

Timer 2 is a 16 bit count down timer (65536 -> 0)

To set up a 1khz timer interrupt, we calculate as follows:

  • Setup CLK divider (1, 4, 16, 32, 64, 128, 256, 512): Ftimer = FCLK_SYS / DIV
  • Set autoReload mode for timer2
  • Calculate the reload value and place it in the reload register
  • counter = period (s) * 1,000,000
  • reload_value = 65536 - (Ftimer * counter)
  • Put into reload register and Enable run timer
  • The interrupt event will be placed in the function Timer2_ISR like the example below
void Timer2_ISR (void) interrupt 5                      // Timer2 ISR funtion
{
	clr_TF2;                                            // Clear Timer2 Interrupt Flag
}

// --------------- Setup ISR timer2 1kHz -----------------------
TIMER2_DIV_4;                           // Đặt xung nhịp Timer2 là FCLK/4 = 16M / 4 = 4M
TIMER2_Auto_Reload_Delay_Mode;          // Đặt Timer2 chế độ auto reload
RCMP2L = TIMER_DIV4_VALUE_1ms;          // Đặt 8 bit thấp của giá trị reload cho thanh ghi reload
                                        // TIMER_DIV4_VALUE_1ms = (65536 - (16,0000,000 / 4  / 1000))
RCMP2H = TIMER_DIV4_VALUE_1ms >> 8;     // Đặt 8 bit cao của giá trị reload cho thanh ghi reload
                                        // TIMER_DIV4_VALUE_1ms = (65536 - (16,0000,000 / 4  / 1000))
TH2 = 0;                                // Thanh ghi chứa giá trị đếm 8bit cao của Timer2
TL2 = 0;                                // Thanh ghi chứa giá trị đếm 8bit thấp của Timer2
set_TR2;                                // Timer2 run
set_ET2;                                // Enable Timer2 interrupt
set_EA;                                 // Enable global interrupts

Read and write EEPROM - Use library LIB\I2Ceeprom.h

 

Reference from the article MS51FB9AE – I2C

  • Includes 2 libraries
  • I2Ceeprom.h used for eeprom ICs with 1k, 2k bits [AT24C01, AT24C02]
  • I2Ceeprom2.h used for other eeprom ICs with larger memory [AT24C04, AT24C08, AT24C16, 32, ...]
  • Functions will return 1 If read, write data successfully and return 0 when it fails

Functions are created

I2C_CheckAddress(address_IC_eeprom);    // Trả về 1 nếu có địa chỉ IC eeprom tồn tại
I2C_write(address, value);              // Ghi 1 byte value vào ô nhớ có địa chỉ address
I2C_writeInt(address, valueInt);        // Ghi data kiểu Int vào ô nhớ có địa chỉ address
I2C_read(address, &var);                // Đọc 1 byte dữ liệu từ địa chỉ address, lưu giá trị vào biến var
I2C_readInt(address, &var);             // Đọc data kiểu Int từ địa chỉ address, lưu giá trị vào biến var
 
#include "I2Ceeprom.h"
#define WAIT_I2C 2      // 2ms write data

void main(void)
{
    char varByte = 0x0;     // 1 byte
    uint16_t varInt;        // 2 byte
    
    // Kiểm tra địa chỉ I2C của IC eeprom có tồn tại không
    if (!I2C_CheckAddress(EEPROM_SLA))  // EEPROM_SLA: mặc định 0xA0 - cấu hình trên phần cứng
        printf("Check Error\n"); 
    
    Timer0_Delay1ms(WAIT_I2C);
    
    	/* write data EEPROM */
    	
	if (!I2C_WriteInt(2, 1234))     // Ghi vào địa chỉ eeprom 2, giá trị kiểu Int 1234
	    printf("Write data Error\n");
	Timer0_Delay1ms(WAIT_I2C);
	    
	if (!I2C_Write(6, 0x04))        // Ghi 1 byte vào địa chỉ eeprom 6, giá trị 0x04 = 4
	    printf("Write data Error\n");
	Timer0_Delay1ms(WAIT_I2C);
	 
	    /* read data EEPROM */
	
	if (!I2C_ReadInt(2, &varInt))   // Đọc dữ liệu kiểu Int (2 byte) ở địa chỉ 4, lưu giá trị vào biến 'varInt'
        printf("Read data Error\n");
    
	if (!I2C_Read(6, &varByte))     // Đọc 1 byte data ở địa chỉ 6, lưu giá trị vào viến varByte   
        printf("Read data Error 3\n");
}