您尚未登录。

楼主 #1 2018-06-08 21:59:54

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

离线

楼主 #2 2018-06-08 22:01:50

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* 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.

QQ20180608220354.jpg

QQ20180608220346.jpg





离线

楼主 #3 2018-06-08 22:20:49

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180608222021.jpg

再次设置 CKDIV 分频器, 可以把10Khz 细分.


下面是系统频率FSYS计算公式:

当 CKDIV = 00H时,
Fsys =Fosc

当 CKDIV = 01H ~ FFH时,
Fsys = Fosc / (2 x CLKDIV)

上图是通过示波器测量 P1.1 (系统时钟输出脚) 引脚的波形和频率.


10000/(2*255) = 19.6 HZ





离线

楼主 #4 2018-06-08 22:34:23

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

这里有一个坑, 芯片只有 OSCIN(P3.0) 引脚, 没有 OSCOUT, 所以只能接有源晶振,不能接无源晶振。





离线

楼主 #5 2018-06-09 08:49:16

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180609084746.png

使用内部10K赫兹, 255(0xFF)分频之后, 通过P1^5 口不断切换高低电平, 逻辑分析仪截图。

从板子上看 P1^5 引脚所接的 LED 1秒约闪两下.





离线

楼主 #6 2018-06-09 09:05:46

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180609090412.png

QQ20180609090159.png

一直没有明白为什么上面的时钟周期是 7 : 4

后来经过Q群友提醒,while(1)跳转也需要指令周期, 查看 N76E003 手册指令周期表,

算出高电平的周期是 4 + 3(SJMP), 低电平周期 4

结果刚好是 7:4





离线

楼主 #7 2018-06-09 10:34:51

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

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);
    }
}




离线

楼主 #8 2018-06-09 10:36:25

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180609103618.png





离线

楼主 #9 2018-06-09 11:07:45

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180609110550.png



上图是 新唐官方例程 N76E003_BSP_Keil_C51_V0.04\Sample_Code\PWM_Simple\PWM.uvproj 逻辑分析仪抓图.

感觉 N76E003 的PWM只能设置为同一频率.





离线

楼主 #10 2018-06-09 11:51:16

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

1. 轮询模式发不出去
2. 中断模式无故进中断

N76E003 uart1(串口1) 真悲催.





离线

楼主 #11 2018-06-09 11:54:14

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

终于搞定了串口1问题,
原来是因为 UART1 与调试口复用,
拔了nu link就正常了。





离线

楼主 #12 2018-06-09 22:38:25

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* 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结构输出电压与带隙电压也不一致。





离线

楼主 #13 2018-06-09 23:09:36

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* 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; //进入掉电模式
		}
}

QQ20180609230818.png

从这个工程修改: N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\WakeupTimer_INT\WKT_INT.uvproj

N76E003 掉电模式与唤醒.





离线

楼主 #14 2018-06-09 23:28:07

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* 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





离线

楼主 #15 2018-06-10 13:34:11

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180610133202.png

打开 C:\Program Files (x86)\Nuvoton Tools\ICPTool\NuMicro ICP Programming Tool.exe 可执行程序,
按照上面5个步骤,
可以设置LDROM 4k, APROM 14k, 现在可以把程序烧到LDROM试一试了。





离线

楼主 #16 2018-06-10 16:59:07

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* 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区域

QQ20180610165813.png

用烧写器把LDROM读出来验证确实编程成功了!





离线

楼主 #17 2018-06-11 11:59:11

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20180611115740.jpg

担心中途又烧板子,又淘了 5块N76E003板子,一个新唐 nu-link仿真器.





离线

#18 2018-07-19 11:47:58

wm20031015
会员
注册时间: 2017-10-18
已发帖子: 65
积分: 169

Re: 新唐 N76E003 8051 1T 单片机入坑记录

修改时钟校准值,实现串口115200bps通信DEMO。

Your text here

离线

#19 2018-07-19 21:02:56

萌萌哒
会员
注册时间: 2018-07-19
已发帖子: 1
积分: 1

Re: 新唐 N76E003 8051 1T 单片机入坑记录

学习学习,刚好最近也在用这颗芯片

离线

#20 2018-07-20 08:48:18

lcfmax
会员
注册时间: 2018-04-13
已发帖子: 319
积分: 272.5

Re: 新唐 N76E003 8051 1T 单片机入坑记录

最近比较火,取代003

离线

#21 2018-07-24 16:41:03

oktony
会员
注册时间: 2018-07-24
已发帖子: 1
积分: 1

Re: 新唐 N76E003 8051 1T 单片机入坑记录

感觉这个芯片总体是挺好的,最大的坑就是无法全部IO口都能中断,只能最大8个管脚中断,还有模块没有独立时钟,AD采样不能独立分频,STM8其实还是无法取代的。

离线

#22 2018-07-24 17:07:41

awfans
会员
注册时间: 2018-04-03
已发帖子: 264
积分: 264

Re: 新唐 N76E003 8051 1T 单片机入坑记录

oktony 说:

感觉这个芯片总体是挺好的,最大的坑就是无法全部IO口都能中断,只能最大8个管脚中断,还有模块没有独立时钟,AD采样不能独立分频,STM8其实还是无法取代的。

总结到位!

离线

#23 2018-10-24 13:05:39

apleilx
会员
注册时间: 2018-10-23
已发帖子: 36
积分: 35

Re: 新唐 N76E003 8051 1T 单片机入坑记录

这个功能比stmf003强大的多又便宜,占了stm涨价的光

离线

#24 2019-01-03 10:07:38

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

用bsp包中例子PWM_Simple工程来测试,发现只有P01输出PWM,其他都没输出,晕哥有遇到这个情况么?

离线

楼主 #25 2019-01-03 10:52:12

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:

用bsp包中例子PWM_Simple工程来测试,发现只有P01输出PWM,其他都没输出,晕哥有遇到这个情况么?

N76E003_BSP_Keil_C51_V1.0.5\Sample_Code\PWM_Simple\PWM.uvproj


P12
P10
P01
P03


刚刚试了一下这个demo, 每路 PWM 都正常!

QQ20190103110845.png





离线

#26 2019-01-03 16:23:35

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

参考了一个台湾同胞的指导文章,用sdcc来编译,结果就只有一路正常。:/
使用SDCC開發新唐N76E003 1T 8051
集成sdcc&makefile

离线

#27 2019-01-03 16:27:10

basicdev
会员
注册时间: 2017-10-02
已发帖子: 159
积分: 159

Re: 新唐 N76E003 8051 1T 单片机入坑记录

建议先走正路,然后再摸石头过河

离线

楼主 #28 2019-01-05 11:03:43

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20190105102116.png

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, 由于新唐升级机制问题,很容易 变砖, 小心操作。





离线

楼主 #29 2019-01-05 11:37:19

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

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;

QQ20190105113505.png

QQ20190105113545.png

从手册里面扣了几行代码, 读 N76E003 的配置 CONFIG 0 .. 4





离线

楼主 #30 2019-01-05 11:58:03

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

$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寄存器成功.





离线

#31 2019-01-05 12:55:23

basicdev
会员
注册时间: 2017-10-02
已发帖子: 159
积分: 159

Re: 新唐 N76E003 8051 1T 单片机入坑记录

这个单片机性价比好,mark

离线

#32 2019-01-05 13:58:33

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

乐趣在于折腾,sdcc编译问题已解决。
原因是sdcc编译|=运算的时候会编译出3条指令,而对于某些受写保护SFR,打开TA保护后只有4个时钟周期是可以写的。
解决方法是通过peep-file来做指令替换,测试pwm例子已正常。集成sdcc&makefile

keil c51编译结果

mov	TA, #0xAA				; TA = 0xAA
mov	TA, #0x55				; TA = 0x55 {'U'}
orl	SFRS, #0x01			; SFRS |= 0x01

未修正前SDCC编译结果

        mov	TA, #0xAA				; TA = 0xAA
	mov	TA, #0x55				; TA = 0x55 {'U'}
	mov	R6, SFRS				; R6 = SFRS
	orl	0x06, #0x01			; 0x06 |= 0x01
	mov	SFRS, R6				; SFRS = R6

离线

楼主 #33 2019-01-05 14:01:20

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

@skcks 感谢分享! 有空试一试 sdcc, 对了, 可以使用 NU-LINK 单步调试吗?





离线

#34 2019-01-05 14:11:21

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:

乐趣在于折腾,sdcc编译问题已解决。
原因是sdcc编译|=运算的时候会编译出3条指令,而对于某些受写保护SFR,打开TA保护后只有4个时钟周期是可以写的。
解决方法是通过peep-file来做指令替换,测试pwm例子已正常。集成sdcc&makefile

keil c51编译结果

mov	TA, #0xAA				; TA = 0xAA
mov	TA, #0x55				; TA = 0x55 {'U'}
orl	SFRS, #0x01			; SFRS |= 0x01

未修正前SDCC编译结果

        mov	TA, #0xAA				; TA = 0xAA
	mov	TA, #0x55				; TA = 0x55 {'U'}
	mov	R6, SFRS				; R6 = SFRS
	orl	0x06, #0x01			; 0x06 |= 0x01
	mov	SFRS, R6				; SFRS = R6

我比较了一下源码:

就 Common.c 多了一个函数:

unsigned char
_sdcc_external_startup (void)
{
    __asm
    mov	0xC7, #0xAA				; [0xC7] = 0xAA
	mov	0xC7, #0x55				; [0xC7] = 0x55 {'U'}
	mov	0xFD, #0x5A				; [0xFD] = 0x5A {'Z'}
	mov	0xC7, #0xAA				; [0xC7] = 0xAA
	mov	0xC7, #0x55				; [0xC7] = 0x55 {'U'}
	mov	0xFD, #0xA5				; [0xFD] = 0xA5
    __endasm;
    return 0;
}

请问这个是解决什么问题呢?

离线

#35 2019-01-05 14:16:20

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

原来是 Makefile

CFLAGS = -I./inc -I$(INCDIR) -m$(MCU_MODEL) --model-$(MODEL) --out-fmt-ihx --no-xinit-opt $(DEBUG) -DFOSC_160000  --peep-filetools/peep.def

tools\peep.def 这个的作用哦

replace {
    mov    %1,%2
    orl    a%1,%3
    mov    %2,%1
} by {
    orl    %2,%3
}

遇到上面三条指令, 就替换成下面一条指令, 真牛人也, 这个问题都能找出来!

离线

#36 2019-01-05 14:28:17

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

以下为是写时效保护寄存器的正确和错误范例:

Example 1,
MOV TA,#0AAH ;3 clock cycles
MOV TA,#55H ;3 clock cycles
ORL WDCON,#data ;4 clock cycles

Example 2,
MOV TA,#0AAH ;3 clock cycles
MOV TA,#55H ;3 clock cycles
NOP ;1 clock cycle
ANL BODCON0,#data ;4 clock cycles

Example 3,
MOV TA,#0AAH ;3 clock cycles
MOV TA,#55H ;3 clock cycles
MOV WDCON,#data1 ;3 clock cycles
ORL BODCON0,#data2 ;4 clock cycles

Example 4,
MOV TA,#0AAH ;3 clock cycles
NOP ;1 clock cycle
MOV TA,#55H ;3 clock cycles
ANL BODCON0,#data ;4 clock cycles

在第一个例子中,写保护位在三个时钟周期窗口关闭之前完成。然而,在例2中,BODCON0的写入并
没有在时效访问窗口打开时完成,操作完这些指令后,BODCON0的值不会有变化。示例3中,WDCON
写入成功,但对BODCON0访问超过三个机器周期窗口,因此BODCON0值不会改变。例4,第二次写
55H对应第一个AAH写入时间超过了3个机器周期,时效访问窗口打开失败,所以后面的写入全部无效。

新唐这寄存器保护也是到位

离线

#37 2019-01-05 14:44:50

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

@jimmy
_sdcc_external_startup会在启动后调用,里面可以做一些初始化的操作,其中的汇编是直接从keil n76e003 bsp的启动文件里面扣出来的,作用是关闭POR功能

离线

#38 2019-01-05 14:51:17

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

晕哥 说:

@skcks 感谢分享! 有空试一试 sdcc, 对了, 可以使用 NU-LINK 单步调试吗?

sdcc用不了NU-LINK,坐等大神逆向开发出解决方案

离线

#39 2019-01-05 14:54:17

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:

@jimmy
_sdcc_external_startup会在启动后调用,里面可以做一些初始化的操作,其中的汇编是直接从keil n76e003 bsp的启动文件里面扣出来的,作用是关闭POR功能

翻了一下手册, 涨知识了:



重要说明:
由于N76E003 POR侦测电压落在1.3V 至 1.5 V范围IE之间,当N76E003进入掉电模式后,再次唤醒
时,N76E003的内核电压可能低于1.5 V,此时可能会触发POR 动作,造成芯片复位。为避免这种现
象,建议当每次电源上电正常运行程序之后,关闭POR模块。

解决方法:
由于POR是用于判断VDD上电状态,当上电状态结束后由LVR来判断电源状态,故建议当稳定上电后,
关闭POR,下面说明如何关闭POR功能。
寄存器PORDIS(FDH)可以用于关闭POR功能。

关闭POR
对PORDIS寄存器先写入5AH,再写入A5H可以关闭POR功能

请严格按照如下步骤关闭POR功能:

sfr PORDIS = 0XFD;
TA =0XAA;
TA= 0X55;
PORDIS = 0X5A;
TA=0XAA;
TA=0X55;
PORDIS = 0XA5;

离线

#40 2019-01-05 14:58:42

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:
晕哥 说:

@skcks 感谢分享! 有空试一试 sdcc, 对了, 可以使用 NU-LINK 单步调试吗?

sdcc用不了NU-LINK,坐等大神逆向开发出解决方案

这个可以有, 但是受众还是太小, 玩51的本来就少了, 玩SDCC的就真凤毛麟角.

离线

#41 2019-02-26 10:13:42

jimmy
会员
注册时间: 2017-10-29
已发帖子: 316
积分: 315

Re: 新唐 N76E003 8051 1T 单片机入坑记录

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

#define T1_INIT        670 

UINT8 u8TH0_Tmp,u8TL0_Tmp,u8TH1_Tmp,u8TL1_Tmp;

UINT16 t = 0;
/************************************************************************************************************
*    TIMER 1 interrupt subroutine
************************************************************************************************************/
void Timer1_ISR (void) interrupt 3  //interrupt address is 0x001B
{
    TH1 = u8TH1_Tmp;
    TL1 = u8TL1_Tmp;   
    t++;
    //P15 = ~P15;                     //P0.3 toggle when interrupt
}
/************************************************************************************************************
*    Main function 
************************************************************************************************************/
void main (void)
{
   
    Set_All_GPIO_Quasi_Mode;

	TIMER1_MODE1_ENABLE;

    clr_T1M;

    u8TH1_Tmp = (65535-T1_INIT)/256;
    u8TL1_Tmp = (65535-T1_INIT)%256;
    
    TH1 = u8TH1_Tmp;
    TL1 = u8TL1_Tmp;
    
    set_ET1;                                    //enable Timer1 interrupt    
    set_EA;                                     //enable interrupts
    t = 0;
    set_TR1;                                    //Timer1 run
    
    while(1)
    {
        if (t >= 2000)
        {
            clr_TR1;
            t = 0;
            P15 = ~P15;                     //P1.5 toggle when interrupt
            set_TR1;
        }
    }
}

几行代码搞定 一个 1秒翻转 IO 的Demo

Da111YxaM.png

离线

#42 2019-02-26 11:30:52

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 27

Re: 新唐 N76E003 8051 1T 单片机入坑记录

离线

楼主 #43 2019-07-12 17:13:39

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

QQ20190712170822.png

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, 两个波特率都正常了。





离线

楼主 #44 2019-07-15 10:46:52

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

添加一个管脚中断程序, 用 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;
    }
}




离线

#45 2020-01-18 21:15:16

WeilunFong
会员
注册时间: 2020-01-18
已发帖子: 1
积分: 1

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:

乐趣在于折腾,sdcc编译问题已解决。
原因是sdcc编译|=运算的时候会编译出3条指令,而对于某些受写保护SFR,打开TA保护后只有4个时钟周期是可以写的。
解决方法是通过peep-file来做指令替换,测试pwm例子已正常。集成sdcc&makefile

keil c51编译结果

mov	TA, #0xAA				; TA = 0xAA
mov	TA, #0x55				; TA = 0x55 {'U'}
orl	SFRS, #0x01			; SFRS |= 0x01

未修正前SDCC编译结果

        mov	TA, #0xAA				; TA = 0xAA
	mov	TA, #0x55				; TA = 0x55 {'U'}
	mov	R6, SFRS				; R6 = SFRS
	orl	0x06, #0x01			; 0x06 |= 0x01
	mov	SFRS, R6				; SFRS = R6

在Github上看到了大佬的解决方案被引用了!上面的另一个解决方案感觉也不错。P.s:关闭POR有种MSP430关闭看门狗的既视感wkaster/N76E003: Nuvoton N76E003 with SDCC

最近编辑记录 WeilunFong (2020-01-18 21:25:30)

离线

#46 2020-03-18 00:02:18

Freeboy
会员
注册时间: 2018-12-03
已发帖子: 42
积分: 167

Re: 新唐 N76E003 8051 1T 单片机入坑记录

跟着晕哥努力学习~

离线

#47 2020-04-06 16:22:52

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

晕哥试过bootloader改成串口1么?有没任何资料说过串口1不能做isp?

离线

楼主 #48 2020-04-06 16:45:38

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 新唐 N76E003 8051 1T 单片机入坑记录

skcks 说:

晕哥试过bootloader改成串口1么?有没任何资料说过串口1不能做isp?

如果用自己的ISP上位机软件,哪个口可以做ISP吧,i2c,spi都行。





离线

#49 2020-04-06 16:49:47

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

晕哥 说:

如果用自己的ISP上位机软件,哪个口可以做ISP吧,i2c,spi都行。

因为串口1复用了icp的管脚,结果改了发现怎么也发不出数据,还未确定是软件问题还是硬件问题。

离线

#50 2020-04-08 15:16:22

skcks
会员
注册时间: 2018-11-08
已发帖子: 10
积分: 10

Re: 新唐 N76E003 8051 1T 单片机入坑记录

搬运了貌似是官方放出的串口烧写的BootLoader到串口1,改成SDCC编译了,上机位要求python3。官方代码乱得一坨,保持了原汁原味,终于可以在macOS下刷程序。
isp_uart1.zip
貌似是官方放出的Nuvoton Standard ISP Code_N76E003.zip

最近编辑记录 skcks (2020-04-08 15:16:51)

离线

#51 2020-04-22 13:31:44

834492956
会员
注册时间: 2020-01-10
已发帖子: 11
积分: 1

Re: 新唐 N76E003 8051 1T 单片机入坑记录

搬运了貌似是官方放出的串口烧写的BootLoader到串口1,

离线

#52 2020-05-18 10:40:08

歌以咏志
会员
注册时间: 2019-09-21
已发帖子: 219
积分: 210

Re: 新唐 N76E003 8051 1T 单片机入坑记录

P1.1死活不能输入, 发现是开了使能时钟输出 set_CLOEN

把这个代码屏蔽就好了。

离线

#53 2020-05-18 15:14:52

yushikong
会员
注册时间: 2017-12-11
已发帖子: 12
积分: 12

Re: 新唐 N76E003 8051 1T 单片机入坑记录

SDCC其实蛮好用的,编译速度很快,特别是linux环境下,windows下面速度也挺快。用好SDCC需要一些技巧,比如你得比较熟悉makefile,以及SDCC里面的一些小坑。我个人做的很多项目都是使用SDCC,除了51单片机外,SDCC也支持STM8的。下面我分享一个新塘单片机的工程文件给大家参考一下
NE76003_SDCC_UART_TEST_20200518-1515.rar

最近编辑记录 yushikong (2020-05-18 15:16:41)

离线

#54 2020-05-18 15:21:56

yushikong
会员
注册时间: 2017-12-11
已发帖子: 12
积分: 12

Re: 新唐 N76E003 8051 1T 单片机入坑记录

编辑环境是windows加eclipse,下面分享几张截图,
none.png  这一张是关于下载程序到单片机里面的配置,稍微等待一下就能下载了,不过不支持在线调试,我一般使用串口直接调试,不怎么用在线调试。



下面说一说eclipse对比keil的优势,其实最主要的是编辑代码的增强,keil特别是C51版本的,基本还停留在上世纪的编辑风格,和windows自带的记事本强不了多少。eclipse具有代码提示、关键词特殊颜色、全局修改变量等等功能,也可以直接搭配git

SDCC时至今日还在活跃的更新,说明还是有一部分人在用的。SDCC里面的一个大坑是关于中断函数,据我个人测试中断函数必须在main函数之前被声明或者直接编写,不然就无法进中断,切记。SDCC编译固件时如果工程里面有较多的无用代码,它也会直接编译到hex里面的,这个问题困扰了我好久,一直没有得到解决。所以如果空间紧张,建议注释掉一些无关的代码,避免代码空间膨胀

最近编辑记录 yushikong (2020-05-18 15:36:14)

离线

#55 2020-05-18 15:40:26

yushikong
会员
注册时间: 2017-12-11
已发帖子: 12
积分: 12

Re: 新唐 N76E003 8051 1T 单片机入坑记录

这里补充一下下载程序的命令,其实很简单,就两行代码

D:\eclipse_sdcc\Nuvoton_Tools\NuLink_Command_Tool\NuLink.exe -e APROM
D:\eclipse_sdcc\Nuvoton_Tools\NuLink_Command_Tool\NuLink.exe -w APROM %1


eclipse_demo.png


有问题的话可以大家一起交流一下

离线

#56 2020-05-18 15:47:14

哇酷小二
wechat微信:whycan_cn
所在地: 你猜
注册时间: 2020-04-22
已发帖子: 3,378
积分: 1902
个人网站

Re: 新唐 N76E003 8051 1T 单片机入坑记录

@yushikong 感谢大佬分享, eclipse + sdcc 这个不错, 但这样调试恐怕不方便了吧?





离线

#57 2020-05-18 15:47:39

shaoxi2010
会员
注册时间: 2019-06-13
已发帖子: 363
积分: 312

Re: 新唐 N76E003 8051 1T 单片机入坑记录

yushikong 说:

编辑环境是windows加eclipse,下面分享几张截图,
https://whycan.cn/files/members/394/none.png  这一张是关于下载程序到单片机里面的配置,稍微等待一下就能下载了,不过不支持在线调试,我一般使用串口直接调试,不怎么用在线调试。



下面说一说eclipse对比keil的优势,其实最主要的是编辑代码的增强,keil特别是C51版本的,基本还停留在上世纪的编辑风格,和windows自带的记事本强不了多少。eclipse具有代码提示、关键词特殊颜色、全局修改变量等等功能,也可以直接搭配git

SDCC时至今日还在活跃的更新,说明还是有一部分人在用的。SDCC里面的一个大坑是关于中断函数,据我个人测试中断函数必须在main函数之前被声明或者直接编写,不然就无法进中断,切记。SDCC编译固件时如果工程里面有较多的无用代码,它也会直接编译到hex里面的,这个问题困扰了我好久,一直没有得到解决。所以如果空间紧张,建议注释掉一些无关的代码,避免代码空间膨胀

关于中断这个当初我也是被坑了好久,后来才发现这个其所在sdcc的手册内是有描诉的,看他的意思除了能放在main对应的那个c文件内,在main的头文件包含也是可以的,不过后面那个场景我没试过。
SDCC allows interrupt service routines to be coded in C, with some extended keywords.
void timer_isr (void) __interrupt (1) __using (1)
{
...
}
The optional number following the __interrupt keyword is the interrupt number this routine will service. When
present, the compiler will insert a call to this routine in the interrupt vector table for the interrupt number specified.
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a
prototype of the isr MUST be present or included in the file that contains the function main. The optional (8051
specific) keyword __using can be used to tell the compiler to use the specified register bank when generating code
for this function.

离线

#58 2020-05-18 16:00:37

yushikong
会员
注册时间: 2017-12-11
已发帖子: 12
积分: 12

Re: 新唐 N76E003 8051 1T 单片机入坑记录

哇酷小二 说:

@yushikong 感谢大佬分享, eclipse + sdcc 这个不错, 但这样调试恐怕不方便了吧?

一般是直接下载程序,重启后看串口信息,或者硬件提示比如数码管、LED灯等,习惯就好

离线

#59 2020-05-18 16:07:52

yushikong
会员
注册时间: 2017-12-11
已发帖子: 12
积分: 12

Re: 新唐 N76E003 8051 1T 单片机入坑记录

shaoxi2010 说:

关于中断这个当初我也是被坑了好久,后来才发现这个其所在sdcc的手册内是有描诉的,看他的意思除了能放在main对应的那个c文件内,在main的头文件包含也是可以的,不过后面那个场景我没试过。
SDCC allows interrupt service routines to be coded in C, with some extended keywords.
void timer_isr (void) __interrupt (1) __using (1)
{
...
}
The optional number following the __interrupt keyword is the interrupt number this routine will service. When
present, the compiler will insert a call to this routine in the interrupt vector table for the interrupt number specified.
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a
prototype of the isr MUST be present or included in the file that contains the function main. The optional (8051
specific) keyword __using can be used to tell the compiler to use the specified register bank when generating code
for this function.

嗯,我一般是直接写一个头文件和源文件包含全部的中断, 这样我感觉会好一些,在芯片的头文件中包含一下即可none_20200518-1606.png

最近编辑记录 yushikong (2020-05-18 17:24:17)

离线

#60 2021-06-22 14:47:35

tigger
Moderator
注册时间: 2021-06-18
已发帖子: 172
积分: 111

Re: 新唐 N76E003 8051 1T 单片机入坑记录

转载: https://www.cnblogs.com/jikexianfeng/p/11024001.html

#include <N76E003.H>
#include <SFR_Macro.h>
#include <Function_Define.h>

bit BIT_TMP;    // 调用 SFR_Macro.h 使用的

void main(void){
    // 开通外部
    set_EXTEN1;
    set_EXTEN0;
    // 等待外部稳定
    while(!(CKSWT|0x08));
    // 选择外部时钟
    clr_OSC1;
    set_OSC0;
    // 等待外部时钟切换成功
    while(CKEN&0x01);
    while(1){
        ;        // 函数主题
    }
}

参考: https://www.cnblogs.com/jikexianfeng/p/9046746.html

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn