英文手册: DS_N76E003_EN_Rev0_04.pdf
中文手册: DS_N76E003_SC_Rev0_04.pdf
英文手册: DS_N76E003_EN_Rev1.06.pdf
中文手册: DS_N76E003_SC_Rev1.06.pdf
keil c51: c51v957.exe
破解补丁: KEIL_Lic.rar
开发板资料下载 QQ群附件: 623495321
开发板资料下载 链接: http://pan.baidu.com/s/1cCeT7g 密码:1n7f
开发板原理图: n76e003_sch.pdf
NU Link仿真器:
https://item.taobao.com/item.htm?id=562773467355
N76E003AT20开发板:
https://item.taobao.com/item.htm?id=562773539677
官方网站bsp下载: N76E003_BSP_Keil_C51_V1.0.5.zip
官方网站bsp下载: N76E003_BSP_Keil_C51_V1.0.6.zip
2019-01-05 添加:
http://www.nuvoton.com/resource-files/Nu-Link_Keil_Driver_V2.05.6815.zip
http://www.nuvoton.com/resource-files/NuMicro_ICP_Programming_Tool_V2.05.6815.zip
本地下载: Nu-Link_Keil_Driver_V2.05.6815.zip
本地下载: NuMicro_ICP_Programming_Tool_V2.05.6815.zip
N76E003_BSP_Keil_C51_V1.0.6.zip
en-us--Nu-Link_Keil_Driver_V3.11.7470r.zip
离线
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2016
//***********************************************************************************************************
//***********************************************************************************************************
// File Function: N76E003 System clock select demo code
//***********************************************************************************************************
#include <stdio.h>
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
//========================================================================
// The test process:
// 1. Power on is run as default HIRC, show LED Fsys tickle faster
// 2. toggle P3.0 to GND.
// 2. call modify Fsys code to LIRC.
// 3. LED tickle speed slowly than before.
//========================================================================
void main(void)
{
/* Note
MCU power on system clock is HIRC (16 MHz)
Please keep P3.0 HIGH before you want to modify Fsys to LIRC
*/
Set_All_GPIO_Quasi_Mode; // In Common.h define
set_CLOEN; // Also can check P1.1 CLO pin for clock to find the Fsys change.
set_P30;
while (P30) // when P3.0 keep high, clock out HIRC
{
clr_GPIO1; // Check LED output tickle time
Timer0_Delay1ms(200);
set_GPIO1;
Timer0_Delay1ms(200);
}
////------------------------------------------------------------------------------------------------------
///*********************************** Change system closk source ***************************************/
////------------------------------------------------------------------------------------------------------
////***** HIRC enable part *****
// set_HIRCEN; //step1: enable HIRC clock source run
// while((CKSWT&SET_BIT5)==0); //step2: check ready
// clr_OSC1; //step3: switching system clock source if needed
// clr_OSC0;
// while((CKEN&SET_BIT0)==1); //step4: check system clock switching OK or NG
//
////***** LIRC enable part*****
////** Since LIRC is always enable, switch to LIRC directly
set_OSC1; //step3: switching system clock source if needed
clr_OSC0;
while((CKEN&SET_BIT0)==1); //step4: check system clock switching OK or NG
clr_HIRCEN;
////--------------------------------------------------------------------------------------------------------
/*
Now Fsys = LIRC , LED tickle slowly.
*/
while(1)
{
clr_GPIO1; // Check LED output tickle time
Timer0_Delay1ms(20);
set_GPIO1;
Timer0_Delay1ms(20);
}
/* =================== */
}
时钟源:
– 16 MHz高速内部振荡器,电源5.0V条件下±1%精度等级。全工作条件范围±2%精度等级.
– 10 kHz低速内部振荡器.
– 支持外部时钟输入.
– 支持系统时钟即时软件切换(On-the-fly)功能.
– 支持软件配置时钟除频最高至1/512.
离线
离线
void main (void)
{
InitialUART0_Timer3(9600); //UART0 Baudrate from Timer3
while(1)
{
Send_Data_To_UART0(0x33);
}
}
上面的例程是 新唐提供 UART0 输出(P06, P07), 一切正常。
但是改成 UART1 之后就不行了。
void main (void)
{
InitialUART1_Timer3(9600); //UART0 Baudrate from Timer3
while(1)
{
Send_Data_To_UART1(0x33);
}
}
离线
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2016
//***********************************************************************************************************
//***********************************************************************************************************
// File Function: N76E885 ADC demo code
//***********************************************************************************************************
#include "N76E003.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "Common.h"
#include "Delay.h"
//***************** The Following is in define in Fucntion_define.h ***************************
//****** Always include Function_define.h call the define you want, detail see main(void) *******
//***********************************************************************************************
#if 0
//#define Enable_ADC_BandGap ADCCON0|=SET_BIT3;ADCCON0&=0xF8; //Band-gap 1.22V
#endif
double Bandgap_Voltage,VDD_Voltage; //please always use "double" mode for this
unsigned char xdata ADCdataH[5], ADCdataL[5];
int ADCsumH=0, ADCsumL=0;
unsigned char ADCavgH,ADCavgL;
void READ_BANDGAP()
{
UINT8 BandgapHigh,BandgapLow,BandgapMark;
double Bandgap_Value,Bandgap_Voltage_Temp;
set_IAPEN;
IAPCN = READ_UID;
IAPAL = 0x0d;
IAPAH = 0x00;
set_IAPGO;
BandgapLow = IAPFD;
BandgapMark = BandgapLow&0xF0;
if (BandgapMark==0x80)
{
BandgapLow = BandgapLow&0x0F;
IAPAL = 0x0C;
IAPAH = 0x00;
set_IAPGO;
BandgapHigh = IAPFD;
Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
Bandgap_Voltage_Temp = Bandgap_Value*3/4;
Bandgap_Voltage = Bandgap_Voltage_Temp - 33; //the actually banggap voltage value is similar this value.
}
if (BandgapMark==0x00)
{
BandgapLow = BandgapLow&0x0F;
IAPAL = 0x0C;
IAPAH = 0x00;
set_IAPGO;
BandgapHigh = IAPFD;
Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
Bandgap_Voltage= Bandgap_Value*3/4;
}
if (BandgapMark==0x90)
{
IAPAL = 0x0E;
IAPAH = 0x00;
set_IAPGO;
BandgapHigh = IAPFD;
IAPAL = 0x0F;
IAPAH = 0x00;
set_IAPGO;
BandgapLow = IAPFD;
BandgapLow = BandgapLow&0x0F;
Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
Bandgap_Voltage= Bandgap_Value*3/4;
}
clr_IAPEN;
// printf ("\n BG High = %bX",BandgapHigh);
// printf ("\n BG Low = %bX",BandgapLow);
// printf ("\n BG ROMMAP = %e",Bandgap_Voltage);
}
/******************************************************************************
The main C function. Program execution starts
here after stack initialization.
******************************************************************************/
void main (void)
{
double bgvalue;
unsigned int i;
InitialUART0_Timer1(115200);
READ_BANDGAP();
Enable_ADC_BandGap;
CKDIV = 0x02; // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
for(i=0;i<5;i++) // All following ADC detect timing is 200uS run under 4MHz.
{
clr_ADCF;
set_ADCS;
while(ADCF == 0);
ADCdataH[i] = ADCRH;
ADCdataL[i] = ADCRL;
}
CKDIV = 0x00; // After ADC sampling, modify system clock back to 16MHz to run next code.
for(i=2;i<5;i++) // use the last 3 times data to make average
{
ADCsumH = ADCsumH + ADCdataH[i];
ADCsumL = ADCsumL + ADCdataL[i];
}
ADCavgH = ADCsumH/3;
ADCavgL = ADCsumL/3;
bgvalue = (ADCavgH<<4) + ADCavgL;
VDD_Voltage = (0x1000/bgvalue)*Bandgap_Voltage;
printf (" BG ROMMAP = %f,",Bandgap_Voltage);
printf (" VDD voltage = %f\n", VDD_Voltage);
while(1);
}
上面这个是工程 N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\ADC_Bandgap\ADC_Bandgap.uvproj 的代码,
用于测量单片机的工作电压,
运行结果
结果显示单片机工作电压 3112mV
BG ROMMAP = 1210.500000, VDD voltage = 3112.497000
换一个电源,测算出来 4722 mV
BG ROMMAP = 1210.500000, VDD voltage = 4722.103000
说明:
N76E003 ADC的第8通道是用来测试内部的带隙电压的,
由于内部带隙电压很稳定,
不会随芯片的工作电压的改变而变化,
所以可以通过测量带隙电压,
然后通过ADC的值便可反推出VCC的电压,
从而用户可以实现自己的低压检测功能。Bandgap voltage reference,常常有人简单地称它为Bandgap。
是利用一个与温度成正比的电压与二极管压降之和,二者温度系数相互抵消,
实现与温度无关的电压基准。因为其基准电压与硅的带隙电压差不多,
因而称为带隙基准。实际上利用的不是带隙电压。
现在有些Bandgap结构输出电压与带隙电压也不一致。
离线
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2017
//***********************************************************************************************************
//***********************************************************************************************************
// File Function: N76E003 wake up timer interrupt demo code
//***********************************************************************************************************
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
void WakeUp_Timer_ISR (void) interrupt 17 //ISR for self wake-up timer
{
clr_GPIO1;
Timer1_Delay10ms(5);
set_GPIO1;
Timer1_Delay10ms(5);
clr_GPIO1;
Timer1_Delay10ms(5);
set_GPIO1;
clr_WKTF; //clear interrupt flag
}
/************************************************************************************************************
* Main function
************************************************************************************************************/
void main (void)
{
P15_PushPull_Mode;
clr_GPIO1;
Timer0_Delay1ms(400);
set_GPIO1;
Timer0_Delay1ms(400);
clr_GPIO1;
Timer0_Delay1ms(400);
set_GPIO1;
Timer0_Delay1ms(400);
clr_GPIO1;
Timer0_Delay1ms(400);
set_GPIO1;
//-----------------------------------------------------
// WKT initial
//-----------------------------------------------------
WKCON = 0x07; //timer base 10k, Pre-scale = 1/16
// RWK = 0XFF; // if prescale is 0x00, never set RWK = 0xff
RWK = 0xF0;
set_EWKT; // enable WKT interrupt
set_WKTR; // Wake-up timer run
EA = 1;
while(1)
{
set_PD; //进入掉电模式
}
}
从这个工程修改: N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\WakeupTimer_INT\WKT_INT.uvproj
N76E003 掉电模式与唤醒.
离线
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2017
//***********************************************************************************************************
//***********************************************************************************************************
// File Function: N76E003 Read actual bandgap value by IAP command
//***********************************************************************************************************
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
UINT8 UID_BYTE(UINT8 Addr)
{
UINT8 DATATEMP;
set_IAPEN;
IAPAL = Addr;
IAPAH = 0x00;
IAPCN = READ_UID;
set_IAPGO;
DATATEMP = IAPFD;
clr_IAPEN;
return DATATEMP;
}
void main(void)
{
UINT8 i = 0;
UINT8 READ[12];
Set_All_GPIO_Quasi_Mode;
InitialUART0_Timer3(115200);
//---------toggle GPIO1---------
clr_GPIO1;
Timer0_Delay1ms(100);
set_GPIO1;
Timer0_Delay1ms(100);
clr_GPIO1;
Timer0_Delay1ms(100);
set_GPIO1;
Timer0_Delay1ms(100);
//---------end toggle GPIO1---------
for(i=0;i<12;i++)
READ[i] = UID_BYTE(i);
while(1)
{
printf("UID: ");
for(i=0;i<12;i++)
{
printf("%bx", READ[i]);
}
printf ("\n");
}
}
工程: N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\IAP_Read_UID\UID.uvproj
读 N76E003 96bit UID
输出结果:
UID: 223100455f3637afb00
UID: 223100455f3637afb00
UID: 223100455f3637afb00
UID: 223100455f3637afb00
UID: 223100455f3637afb00
离线
离线
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
//***********************************************************************************************************
// Nuvoton Technoledge Corp.
// Website: http://www.nuvoton.com
// E-Mail : MicroC-8bit@nuvoton.com
// Date : Apr/21/2017
//***********************************************************************************************************
//***********************************************************************************************************
// File Function: N76E003 APROM program DATAFLASH (APROM) demo code
//***********************************************************************************************************
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#define CID_READ 0x0B
#define DID_READ 0x0C
/*
Since the DATAFLASH is in the APROM. Program command is same as program APROM
*/
#define PAGE_ERASE_LD 0x62
#define BYTE_READ_LD 0x40
#define BYTE_PROGRAM_LD 0x61
#define PAGE_SIZE 128
#define ERASE_FAIL 0x70
#define PROGRAM_FAIL 0x71
#define IAPFF_FAIL 0x72
#define IAP_PASS 0x00
//---------------------------------------------------------------
// Following define by customer
// Please confirm the start addresss not over your code size
//---------------------------------------------------------------
#define DATA_SIZE 1024*4
#define DATA_START_ADDR 0x0000
/********************************************************************************************
Following IAP command register is also define in SFR_Macro.h
#define set_IAPEN BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON |= SET_BIT0 ;EA=BIT_TMP
#define clr_IAPEN BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON &= ~SET_BIT0;EA=BIT_TMP
#define set_APUEN BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN |= SET_BIT0 ;EA=BIT_TMP
#define clr_APUEN BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN &= ~SET_BIT0;EA=BIT_TMP
**********************************************************************************************/
void IAP_ERROR_LED(void)
{
while (1)
{
clr_P03;
Timer0_Delay1ms(100);
set_P03;
Timer0_Delay1ms(100);
}
}
//-----------------------------------------------------------------------------------------------------------/
void Trigger_IAP(void)
{
set_IAPGO; //trigger IAP
if((CHPCON&SET_BIT6)==SET_BIT6) // if fail flag is set, toggle error LED and IAP stop
{
clr_IAPFF;
IAP_ERROR_LED();
}
}
/*
WARNING:
No matter read or writer, when IAPFF is set 1,
this step process is fail. DATA should be ignore.
*/
//-----------------------------------------------------------------------------------------------------------/
/*****************************************************************************************************************
Erase APROM subroutine:
******************************************************************************************************************/
void Erase_LDROM(void)
{
UINT16 u16Count;
set_IAPEN; // Enable IAP function
IAPFD = 0xFF; // IMPORTANT !! To erase function must setting IAPFD = 0xFF
IAPCN = PAGE_ERASE_LD;
set_LDUEN; // APROM modify Enable
for(u16Count=0x0000;u16Count<DATA_SIZE/PAGE_SIZE;u16Count++) //
{
IAPAL = LOBYTE(u16Count*PAGE_SIZE + DATA_START_ADDR);
IAPAH = HIBYTE(u16Count*PAGE_SIZE + DATA_START_ADDR);
Trigger_IAP();
}
// clr_LDUEN;
// clr_IAPEN;
}
//-----------------------------------------------------------------------------------------------------------
void Erase_LDROM_Verify(void)
{
UINT16 u16Count;
set_IAPEN;
IAPAL = LOBYTE(DATA_START_ADDR);
IAPAH = HIBYTE(DATA_START_ADDR);
IAPCN = BYTE_READ_LD;
for(u16Count=0;u16Count<DATA_SIZE;u16Count++)
{
IAPFD = 0x00;
Trigger_IAP();
if(IAPFD != 0xFF)
IAP_ERROR_LED();
IAPAL++;
if(IAPAL == 0x00)
IAPAH++;
}
clr_IAPEN;
}
//-----------------------------------------------------------------------------------------------------------
void Program_LDROM(void)
{
UINT16 u16Count;
set_IAPEN;
set_LDUEN;
IAPAL = LOBYTE(DATA_START_ADDR);
IAPAH = HIBYTE(DATA_START_ADDR);
IAPCN = BYTE_PROGRAM_LD;
for(u16Count=0;u16Count<DATA_SIZE;u16Count++)
{
IAPFD++;
Trigger_IAP();
IAPAL++;
if(IAPAL == 0)
{
IAPAH++;
}
}
clr_LDUEN;
clr_IAPEN;
}
//-----------------------------------------------------------------------------------------------------------
void Program_LDROM_Verify(void)
{
UINT16 u16Count;
UINT8 u8Read_Data;
set_IAPEN;
IAPAL = LOBYTE(DATA_START_ADDR);
IAPAH = HIBYTE(DATA_START_ADDR);
IAPCN = BYTE_READ_LD;
u8Read_Data = 0x00;
for(u16Count=0;u16Count<DATA_SIZE;u16Count++)
{
Trigger_IAP();
if(IAPFD != u8Read_Data)
IAP_ERROR_LED();
IAPAL++;
if(IAPAL == 0)
{
IAPAH++;
}
u8Read_Data ++;
}
clr_IAPEN;
}
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
void main (void)
{
Set_All_GPIO_Quasi_Mode;
//---------toggle GPIO1---------
clr_GPIO1;
Timer0_Delay1ms(100);
set_GPIO1;
Timer0_Delay1ms(100);
clr_GPIO1;
Timer0_Delay1ms(100);
set_GPIO1;
Timer0_Delay1ms(100);
//---------end toggle GPIO1---------
Erase_LDROM();
Erase_LDROM_Verify();
Program_LDROM();
Program_LDROM_Verify();
//---------toggle GPIO1---------
clr_GPIO1;
//---------end toggle GPIO1---------
while(1);
}
//-----------------------------------------------------------------------------------------------------------
N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\IAP_AP-program-LD\IAP_APproLD.uvproj
这个例程演示的是在程序中(APPROM)编程 LDROM区域
用烧写器把LDROM读出来验证确实编程成功了!
离线
离线
2.0版本相关工具有bug, 下载最新的工具集试一试:
https://www.nuvoton.com/hq/support/tool-and-software/software/development-tool/?__locale=en
http://www.nuvoton.com/resource-files/Nu-Link_Keil_Driver_V2.05.6815.zip
http://www.nuvoton.com/resource-files/NuMicro_ICP_Programming_Tool_V2.05.6815.zip
更新软件会强制刷新 NU-LINK, 由于新唐升级机制问题,很容易 变砖, 小心操作。
离线
START.A51:
$INCLUDE (N76E003.INC)
;******************************************************************************
; This code illustrates how to use IAP to make APROM 201h as a byte of
; Data Flash when user code is executed in APROM.
;******************************************************************************
ALL_ERASE_CONFIG EQU 11100010b
BYTE_PROGRAM_CONFIG EQU 11100001b
BYTE_READ_CONFIG EQU 11000000b
ORG 0000h
CALL Enable_IAP
CALL Read_CONFIG ;read back CONFIG2
CALL Disable_IAP
SJMP $
Enable_IAP:
MOV TA,#0Aah ;CHPCON is TA protected
MOV TA,#55h
ORL CHPCON,#00000001b ;IAPEN = 1, enable IAP mode
RET
Disable_IAP:
MOV TA,#0Aah
MOV TA,#55h
ANL CHPCON,#11111110b ;IAPEN = 0, disable IAP mode
RET
Read_CONFIG:
MOV IAPCN,#BYTE_READ_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
CALL Trigger_IAP
MOV R3,IAPFD
MOV IAPAL,#01h
CALL Trigger_IAP
MOV R4,IAPFD
MOV IAPAL,#02h
CALL Trigger_IAP
MOV R5,IAPFD
MOV IAPAL,#03h
CALL Trigger_IAP
MOV R6,IAPFD
MOV IAPAL,#04h
CALL Trigger_IAP
MOV R7,IAPFD
RET
Trigger_IAP:
MOV TA,#0Aah ;IAPTRG is TA protected
MOV TA,#55h
ORL IAPTRG,#00000001b ;write ‘1’ to IAPGO to trigger IAP process
RET
END
N76E003.INC:
RCTRIM0 EQU 0x84;
RCTRIM1 EQU 0x85;
RWK EQU 0x86;
CKCON EQU 0x8E;
WKCON EQU 0x8F;
SFRS EQU 0x91; //TA Protection
CAPCON0 EQU 0x92;
CAPCON1 EQU 0x93;
CAPCON2 EQU 0x94;
CKDIV EQU 0x95;
CKSWT EQU 0x96; //TA Protection
CKEN EQU 0x97; //TA Protection
SBUF_1 EQU 0x9A;
EIE EQU 0x9B;
EIE1 EQU 0x9C;
CHPCON EQU 0x9F; //TA Protection
AUXR1 EQU 0xA2;
BODCON0 EQU 0xA3; //TA Protection
IAPTRG EQU 0xA4; //TA Protection
IAPUEN EQU 0xA5; //TA Protection
IAPAL EQU 0xA6;
IAPAH EQU 0xA7;
SADDR EQU 0xA9;
WDCON EQU 0xAA; //TA Protection
BODCON1 EQU 0xAB; //TA Protection
P3M1 EQU 0xAC;
P3S EQU 0xAC; //Page1
P3M2 EQU 0xAD;
P3SR EQU 0xAD; //Page1
IAPFD EQU 0xAE;
IAPCN EQU 0xAF;
P0M1 EQU 0xB1;
P0S EQU 0xB1; //Page1
P0M2 EQU 0xB2;
P0SR EQU 0xB2; //Page1
P1M1 EQU 0xB3;
P1S EQU 0xB3; //Page1
P1M2 EQU 0xB4;
P1SR EQU 0xB4; //Page1
P2S EQU 0xB5;
IPH EQU 0xB7;
PWMINTC EQU 0xB7; //Page1
SADEN EQU 0xB9;
SADEN_1 EQU 0xBA;
SADDR_1 EQU 0xBB;
I2DAT EQU 0xBC;
I2STAT EQU 0xBD;
I2CLK EQU 0xBE;
I2TOC EQU 0xBF;
I2CON EQU 0xC0;
I2ADDR EQU 0xC1;
ADCRL EQU 0xC2;
ADCRH EQU 0xC3;
T3CON EQU 0xC4;
PWM4H EQU 0xC4; //Page1
RL3 EQU 0xC5;
PWM5H EQU 0xC5; //Page1
RH3 EQU 0xC6;
PIOCON1 EQU 0xC6; //Page1
TA EQU 0xC7;
T2CON EQU 0xC8;
T2MOD EQU 0xC9;
RCMP2L EQU 0xCA;
RCMP2H EQU 0xCB;
TL2 EQU 0xCC;
PWM4L EQU 0xCC; //Page1
TH2 EQU 0xCD;
PWM5L EQU 0xCD; //Page1
ADCMPL EQU 0xCE;
ADCMPH EQU 0xCF;
PWMPH EQU 0xD1;
PWM0H EQU 0xD2;
PWM1H EQU 0xD3;
PWM2H EQU 0xD4;
PWM3H EQU 0xD5;
PNP EQU 0xD6;
FBD EQU 0xD7;
PWMCON0 EQU 0xD8;
PWMPL EQU 0xD9;
PWM0L EQU 0xDA;
PWM1L EQU 0xDB;
PWM2L EQU 0xDC;
PWM3L EQU 0xDD;
PIOCON0 EQU 0xDE;
PWMCON1 EQU 0xDF;
ADCCON1 EQU 0xE1;
ADCCON2 EQU 0xE2;
ADCDLY EQU 0xE3;
C0L EQU 0xE4;
C0H EQU 0xE5;
C1L EQU 0xE6;
C1H EQU 0xE7;
ADCCON0 EQU 0xE8;
PICON EQU 0xE9;
PINEN EQU 0xEA;
PIPEN EQU 0xEB;
PIF EQU 0xEC;
C2L EQU 0xED;
C2H EQU 0xEE;
EIP EQU 0xEF;
CAPCON3 EQU 0xF1;
CAPCON4 EQU 0xF2;
SPCR EQU 0xF3;
SPCR2 EQU 0xF3; //Page1
SPSR EQU 0xF4;
SPDR EQU 0xF5;
AINDIDS EQU 0xF6;
EIPH EQU 0xF7;
SCON_1 EQU 0xF8;
PDTEN EQU 0xF9; //TA Protection
PDTCNT EQU 0xFA; //TA Protection
PMEN EQU 0xFB;
PMD EQU 0xFC;
EIP1 EQU 0xFE;
EIPH1 EQU 0xFF;
从手册里面扣了几行代码, 读 N76E003 的配置 CONFIG 0 .. 4
离线
$INCLUDE (N76E003.INC)
;******************************************************************************
; This code illustrates how to use IAP to make APROM 201h as a byte of
; Data Flash when user code is executed in APROM.
;******************************************************************************
ALL_ERASE_CONFIG EQU 11100010b
BYTE_PROGRAM_CONFIG EQU 11100001b
BYTE_READ_CONFIG EQU 11000000b
ORG 0000h
CALL Enable_IAP
CALL Read_CONFIG ;read back CONFIG2
CALL Enable_CONFIG_Update
CALL Erase_CONFIG ;erase CONFIG bytes
CALL Program_CONFIG ;programming CONFIG2 with new data
CALL Disable_CONFIG_Update
CALL Program_CONFIG_Verify ;verify Programmed CONFIG2
CALL Read_CONFIG ;read back CONFIG2
CALL Disable_IAP
SJMP $
Enable_IAP:
MOV TA,#0Aah ;CHPCON is TA protected
MOV TA,#55h
ORL CHPCON,#00000001b ;IAPEN = 1, enable IAP mode
RET
Disable_IAP:
MOV TA,#0Aah
MOV TA,#55h
ANL CHPCON,#11111110b ;IAPEN = 0, disable IAP mode
RET
Read_CONFIG:
MOV IAPCN,#BYTE_READ_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
CALL Trigger_IAP
MOV R3,IAPFD
MOV IAPAL,#01h
CALL Trigger_IAP
MOV R4,IAPFD
MOV IAPAL,#02h
CALL Trigger_IAP
MOV R5,IAPFD
MOV IAPAL,#03h
CALL Trigger_IAP
MOV R6,IAPFD
MOV IAPAL,#04h
CALL Trigger_IAP
MOV R7,IAPFD
RET
Trigger_IAP:
MOV TA,#0Aah ;IAPTRG is TA protected
MOV TA,#55h
ORL IAPTRG,#00000001b ;write ‘1’ to IAPGO to trigger IAP process
RET
Enable_CONFIG_Update:
MOV TA,#0Aah
MOV TA,#55h
ORL IAPUEN,#00000100b ;CFUEN = 1, enable CONFIG update
RET
Disable_CONFIG_Update:
MOV TA,#0Aah
MOV TA,#55h
ANL IAPUEN,#11111011b ;CFUEN = 0, disable CONFIG update
RET
;********************************************************************
; IAP CONFIG Function
;********************************************************************
Erase_CONFIG:
MOV IAPCN,#ALL_ERASE_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
MOV IAPFD,#0FFh
CALL Trigger_IAP
RET
Program_CONFIG:
MOV IAPCN,#BYTE_PROGRAM_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#02h
MOV A,R7
ANL A,#11111011b
MOV IAPFD,A ;disable BOD reset
MOV R6,A ;temp data
CALL Trigger_IAP
RET
Program_CONFIG_Verify:
MOV IAPCN,#BYTE_READ_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#02h
CALL Trigger_IAP
MOV B,R6
MOV A,IAPFD
CJNE A,B,Program_CONFIG_Verify_Error
RET
Program_CONFIG_Verify_Error:
CALL Disable_IAP
MOV P0,#00h
SJMP $
END
写 N76E003 的 CONFIG2 成功
$INCLUDE (N76E003.INC)
;******************************************************************************
; This code illustrates how to use IAP to make APROM 201h as a byte of
; Data Flash when user code is executed in APROM.
;******************************************************************************
ALL_ERASE_CONFIG EQU 11100010b
BYTE_PROGRAM_CONFIG EQU 11100001b
BYTE_READ_CONFIG EQU 11000000b
ORG 0000h
CALL Enable_IAP
CALL Read_CONFIG ;read back CONFIG2
CALL Enable_CONFIG_Update
CALL Erase_CONFIG ;erase CONFIG bytes
CALL Program_CONFIG ;programming CONFIG2 with new data
CALL Disable_CONFIG_Update
CALL Program_CONFIG_Verify ;verify Programmed CONFIG2
CALL Read_CONFIG ;read back CONFIG2
CALL Disable_IAP
SJMP $
Enable_IAP:
MOV TA,#0Aah ;CHPCON is TA protected
MOV TA,#55h
ORL CHPCON,#00000001b ;IAPEN = 1, enable IAP mode
RET
Disable_IAP:
MOV TA,#0Aah
MOV TA,#55h
ANL CHPCON,#11111110b ;IAPEN = 0, disable IAP mode
RET
Read_CONFIG:
MOV IAPCN,#BYTE_READ_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
CALL Trigger_IAP
MOV R3,IAPFD
MOV IAPAL,#01h
CALL Trigger_IAP
MOV R4,IAPFD
MOV IAPAL,#02h
CALL Trigger_IAP
MOV R5,IAPFD
MOV IAPAL,#03h
CALL Trigger_IAP
MOV R6,IAPFD
MOV IAPAL,#04h
CALL Trigger_IAP
MOV R7,IAPFD
RET
Trigger_IAP:
MOV TA,#0Aah ;IAPTRG is TA protected
MOV TA,#55h
ORL IAPTRG,#00000001b ;write ‘1’ to IAPGO to trigger IAP process
RET
Enable_CONFIG_Update:
MOV TA,#0Aah
MOV TA,#55h
ORL IAPUEN,#00000100b ;CFUEN = 1, enable CONFIG update
RET
Disable_CONFIG_Update:
MOV TA,#0Aah
MOV TA,#55h
ANL IAPUEN,#11111011b ;CFUEN = 0, disable CONFIG update
RET
;********************************************************************
; IAP CONFIG Function
;********************************************************************
Erase_CONFIG:
MOV IAPCN,#ALL_ERASE_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
MOV IAPFD,#0FFh
CALL Trigger_IAP
RET
Program_CONFIG:
MOV IAPCN,#BYTE_PROGRAM_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#00h
MOV A,R7
ANL A,#6Fh
MOV IAPFD,A ;disable BOD reset
MOV R6,A ;temp data
CALL Trigger_IAP
MOV IAPAL,#01h
MOV A,R7
ANL A,#0FBh
MOV IAPFD,A ;disable BOD reset
MOV R6,A ;temp data
CALL Trigger_IAP
MOV IAPAL,#02h
MOV A,R7
ANL A,#0FBh
MOV IAPFD,A ;disable BOD reset
MOV R6,A ;temp data
CALL Trigger_IAP
RET
Program_CONFIG_Verify:
MOV IAPCN,#BYTE_READ_CONFIG
MOV IAPAH,#00h
MOV IAPAL,#02h
CALL Trigger_IAP
MOV B,R6
MOV A,IAPFD
CJNE A,B,Program_CONFIG_Verify_Error
RET
Program_CONFIG_Verify_Error:
CALL Disable_IAP
MOV P0,#00h
SJMP $
END
写三个CONFIG寄存器成功.
离线
16Mhz 下明明 9600bps 和 38400bps 的误差率是一致,
但是两个批次的N76E003, 有一个批次上面两个波特率正常,
有一个批次,38400bsp 不正常, 而9600bps 正常.
void MODIFY_HIRC_166(void) // Modify HIRC to 16.6MHz, more detail please see datasheet V1.02
{
UINT8 hircmap0,hircmap1;
UINT16 trimvalue16bit;
/* Check if power on reset, modify HIRC */
if ((PCON&SET_BIT4)==SET_BIT4)
{
hircmap0 = RCTRIM0;
hircmap1 = RCTRIM1;
trimvalue16bit = ((hircmap0<<1)+(hircmap1&0x01));
trimvalue16bit = trimvalue16bit - 15;
hircmap1 = trimvalue16bit&0x01;
hircmap0 = trimvalue16bit>>1;
TA=0XAA;
TA=0X55;
RCTRIM0 = hircmap0;
TA=0XAA;
TA=0X55;
RCTRIM1 = hircmap1;
/* Clear power on flag */
PCON &= CLR_BIT4;
}
}
void main (void)
{
UINT8 c;
MODIFY_HIRC_166();
set_CLOEN; //Check HIRC out wavefrom to confirm the HIRC modified
InitialUART0_Timer1(38400);
while(1)
{
if(RI)
{
c = SBUF;
RI = 0;
Send_Data_To_UART0(c);
}
}
}
修正到 16.6Mhz, 两个波特率都正常了。
离线
添加一个管脚中断程序, 用 P1 这组口, 引脚需要上拉, 可以从掉电模式唤醒,电流未测。
源码下载: Pin_Interrupt_20190715.7z
bit PIFlag;//管脚中断标志位
sbit LED=P1^5;
void main (void)
{
Set_All_GPIO_Quasi_Mode;
//设置为输入模式
P10_Input_Mode;
P11_Input_Mode;
P12_Input_Mode;
clr_PIPS1;
set_PIPS0;//选择P1为中断输入源
//Enable_BIT1_HighLevel_Trig; //高电平触发管脚中断
//Enable_BIT1_FallEdge_Trig; //下降沿
//Enable_BIT1_RasingEdge_Trig;//上升沿
Enable_BIT2_LowLevel_Trig;
Enable_BIT1_LowLevel_Trig; //低电平
Enable_BIT0_LowLevel_Trig;
LED=1;//初始化LED端口
Timer0_Delay1ms(20);
set_EPI;//开启管脚中断使能
EA = 1;//开启总中断
while(1)
{
if(PIFlag)//判定是否溢出
{
LED=0;
Timer0_Delay1ms(10);
LED=1;//灯闪烁
PIFlag=0;
ADCCON1 = 0X00;//关闭ADC
clr_BODEN;//关闭欠压检测
set_PD;// 进入掉电模式
}
}
}
//-------管脚中断中断服务程序---------
void PinInterrupt (void) interrupt 7
{
if((PIF & 0x01) == 0x01)//P10位于 0通道
{
PIF=0;//清除外部中断标志
PIFlag=1;
}
else if((PIF & 0x02) == 0x02)//P11位于 1通道
{
PIF=0;//清除外部中断标志
PIFlag=1;
}
else if((PIF & 0x04) == 0x04)//P12位于 2通道
{
PIF=0;//清除外部中断标志
PIFlag=1;
}
}
离线