[Not Solved] ][Embedded] [FL2440] ADS实验六: ADC实验: 还没有完全理解代码

时间:2021-07-28 08:59:41


1.6-adc\init.s

============================================================================================================

	AREA |DATA|,CODE,READONLY
	ENTRY
	ldr r13, =0x1000	; Set sp
	IMPORT adcMain
	b adcMain
	END


1.6-adc\include.h

============================================================================================================

#ifndef include_h
#define include_h

// nand
#define rNFCONF	(*(volatile unsigned *)0x4e000000)
#define rNFCONT (*(volatile unsigned *)0x4e000004)
#define rNFCMD  (*(volatile unsigned *)0x4e000008)
#define rNFADDR (*(volatile unsigned *)0x4e00000c)
#define rNFDATA (*(volatile unsigned *)0x4e000010)
#define rNFDATA8 (*(volatile unsigned char *)0x4e000010)
#define rNFMECC0 (*(volatile unsigned *)0x4e00002c)
#define rNFSTAT (*(volatile unsigned *)0x4e000020)
#define rNFESTAT0 (*(volatile unsigned *)0x4e000024)

// uart
#define rUTRSTAT0 (*(volatile unsigned *)0x50000010)	// UART 0 Tx/Rx status
#define rULCON0	  (*(volatile unsigned *)0x50000000)	// UART 0 Line Control
#define rUCON0	  (*(volatile unsigned *)0x50000004)	// UART 0 Control
#define rUFCON0	  (*(volatile unsigned *)0x50000008)	// UART 0 FIFO control
#define rUBRDIV0  (*(volatile unsigned *)0x50000028) // UART 0 Baud rate divisor
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
#define RdURXH0() (*(volatile unsigned char *)0x50000027)

// adc
#define rADCCON (*(volatile unsigned *)0x58000000)
#define rADCDAT0 (*(volatile unsigned *)0x5800000c)


#define EnNandFlash()	(rNFCONT |= 1)	// Enable Nand Flash controller
#define DsNandFlash()	(rNFCONT &= ~1) // Disable NF controller
#define NFChipEn()	(rNFCONT &= ~(1 << 1)) // Enable chip select
#define NFChipDs()	(rNFCONT |= (1 << 1))  // Disable chip select
#define InitEcc()	(rNFCONT |= (1 << 4)) // init ECC decoder/encoder
#define MEccUnlock()	(rNFCONT &= ~(1 << 5))
#define MEccLock()	(rNFCONT != (1 << 5))
#define SEccUnlock()	(rNFCONT &= ~(1 << 6))
#define SEccLock()	(rNFCONT != (1 << 6))

#define WrNFDat8(dat)	(rNFDATA8 = (dat))
#define WrNFDat32(da)	(rNFDATA = (dat))
#define RdNFDat8()	(rNFDATA8)	// byte access
#define RdNFDat32()	(rNFDATA)	// word access

#define WrNFCmd(cmd)	(rNFCMD = (cmd))
#define WrNFAddr(addr)	(rNFADDR = (addr))
#define WrNFDat(dat)	WrNFDat8(dat)
#define RdNFdat()	RdNFDat8()  // for 8 bit nand flash, use byte access

#define RdNFMEcc()	(rNFMECC0) // for 8 bit nand flash, only use NFMECC0
#define RdNFSEcc()	(rNFSECC)  // for 8 bit nand flash, only use low 16 bits

#define RdNFStat	(rNFSTAT)
#define NFIsBusy	(!(rNFSTAT & 1))
#define NFIsReady	(rNFSTAT & 1)


#define READCMD0	0
#define READCMD1	0x30
#define EREASECMD0	0x60
#define EREASECMD1	0xd0
#define PROGCMD0	0x80
#define PROGCMD1	0x10
#define QUERYCMD	0x70
#define	RdIDCMD		0x90

#define TACLS		1	// 7 1-clk (0ns)
#define TWRPH0		4	// 7 3-clk (25ns)
#define TWRPH1		1	// 7 1-clk (10ns)

#define U32 unsigned int
#define U16  unsigned short
#define S32  int
#define S16  short int
#define U8   unsigned char
#define S8   char

#define	TRUE 1
#define FALSE 0

#define OK 1
#define FAIL 0

#define ESC_KEY 0x1b

#endif


1.6-adc/uart.c

============================================================================================================

#include "include.h"
#include <stdarg.h>

void Uart_Init(int baud)
{
	int i;
	rUFCON0 = 0x0; // UART channel 0 FIFO control register, FIFO disable

	// UART 0
	// Line control register: Normal, No parioty, 1 stop, 8 bits
	rULCON0 = 0x3;	

	rUCON0 = 0x805;	// Control register
	// Baud rate divisor register 0
	rUBRDIV0 = ((int)(50000000 / 16.0 / baud + 0.5) - 1);

	// UART 1
	for (i = 0; i < 100; i++)
		;
}

void Uart_SendByte(int data)
{
	if (data == '\n') {
		while (!(rUTRSTAT0 & 0x2))
			;
		// delay(1); // because the slow response of hyper_terminal
		WrUTXH0('\r');
	}
	while (!(rUTRSTAT0 & 0x2)) // Wait until THR is empty
		;
	// delay(1);
	WrUTXH0(data);
}

void Uart_SendString(S8 *pt)
{
	while (*pt)
		Uart_SendByte(*pt++);
}

// If you don't use vsprintf(), the code size is reduced very much
void Uart_Printf(S8 *fmt, ...)
{
	va_list ap;
	S8 str[255];

	va_start(ap, fmt);
	vsprintf(str, fmt, ap);
	Uart_SendString(str);
	va_end(ap);
}


1.6-adc/main.c

============================================================================================================

/* by Dooit.Lee@gmail.com
 * Refer to: www.witech.com.cn
 */
/**********************按键实验*********************************/
// 公司名称 :保定飞凌嵌入式技术有限公司
// 描    述 :ADC数据采集
// 版    权 :保定飞凌嵌入式技术有限公司
// 网    址 :www.witech.com.cn
/***************************************************************/

#include "include.h"

/*-------------------------- 地址声明 ---------------------------------*/
#define rUTXH0 (*(volatile unsigned *)0x50000020)
#define rURXH0 (*(volatile unsigned *)0x50000024)

/*--------------------------- 变量定义 --------------------------------*/
U32 ADC_FREQ = 115200 * 16;
U32 preScaler;

/*--------------------------- Declare functions -----------------------*/
void delay(int count);
char Uart_GetKey(void);
int ReadAd(void);
void Test_Adc(void);

/*
 * Function: 	delay
 * DESC:	delay 'count' ms
 * Param:	int count
 * RETURN:	None
 */
void delay(int count)
{
	unsigned int i;
	while (--count != 0) {
		for (i = 0; i < 0xff; i++)
			;
	}
}

/*
 * Function:	Uart_GetKey
 * DESC:	判断接收到的串口
 * Param:	None
 * RETURN:	rURXH0
 */
char Uart_GetKey(void)
{
	if (rUTRSTAT0 & 0x01)
		return rURXH0;
	else
		return 0;
}

/*
 * Function: 	adcMain
 * DESC:	Entry program
 * Param:	None
 * RETURN:	None
 */
void adcMain(void)
{
	U8	i;
	Uart_Init(115200); // 出事换串口
	Test_Adc();	// 进入采样
	while (1) ;
}

/*
 * Function: 	ReadAd
 * DESC:	读取ADCCON, ADCDAT, 返回当次采样值
 * Param:	None
 * RETURN:	int
 */
int ReadAd(void)
{
	// 打开预分频器,设置预分频数,设置ADC通道,设置为AIN0
	rADCCON = (1 << 14) | (49 << 6) | (0 << 3);
	// 开始ADC, 真正开始转换时, ENABLE_START自动清0
	rADCCON |= 0x1;
	// 等待ADC使能位ENABlE_START置零
	while (rADCCON & 0x1)
		;
	// 等待本次ADC采样结束, EGFLG位置1后表示转换结束
	while (!(rADCCON & 0x8000))
		;
	// 采样值范围: 0 ~ 0x3ff 低10位为采样有效数据
	return ((int)rADCDAT0 & 0x3ff);
}

/*
 * Function: 	Test_Adc
 * DESC:	采样ADC值并想串口输出数据
 * Param:	None
 * RETURN:	None
 */
void Test_Adc(void)
{
	int a0 = 0;	// 用来保存采样函数返回的采样值
	// 本开发版PCLK: 50MHz
	preScaler = 50000000 / ADC_FREQ - 1;
	// 给串口输出采样率
	Uart_Printf("PCL / ADC_FREQ - 1 = %d\n", preScaler);
	// 收到退出信号后退出 while
	while (Uart_GetKey() != ESC_KEY) {
		a0 = ReadAd();
		// 向串口输出本次采样到的数值
		Uart_Printf("AIN0: %04d\n", a0);
		delay(500);
	}

	Uart_Printf("\nADC INPUT Test over!\n");
}