📄 44blib.c
字号:
/************************************************
* NAME : 44BLIB.C *
* Version : 1.1 *
* *
* 描述:构建一个实用的函数库 *
* *
************************************************/
#include "44b.h"
#include "44blib.h"
#include "def.h"
#include "option.h"
/************************************************
* 下面有些函数使用了ARM的运行时库 *
* 所以要包含这些头文件 *
* *
************************************************/
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
/************************************************
* *
* 给我们的简单内存管理(堆管理)定义内存空间 *
* *
************************************************/
#define HEAPEND (_ISR_STARTADDRESS-0x2000) // = 0xc7fe000
#define Uart1Enable (*(volatile unsigned char *)0x6680000)=0xfd
#define Uart1Disable (*(volatile unsigned char *)0x6680000)=0x02
extern char Image$$RW$$Limit[];
void *mallocPt=Image$$RW$$Limit;
/********************************************************
* 函数名称:Delay 常用延时函数 *
* 描 述:100us的分辨率 *
* 输入参数:time *
* time=0时用WatchDog的定时器调整延时循环赋值*
* time>0时 程序延时 time*100us 长时间 *
********************************************************/
static int delayLoopCount=400;
void Delay(int time)
{
int i,adjust=0;
if(time==0)
{
time=200;
adjust=1;
delayLoopCount=400;
rWTCON=((MCLK/1000000-1)<<8)|(2<<3); //MCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable
rWTDAT=0xffff; //第一次更正
rWTCNT=0xffff; //分辨率=64us(在任何主频下)
rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer start
}
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
if(adjust==1)
{
rWTCON=((MCLK/1000000-1)<<8)|(2<<3); //Watch-dog timer stop
i=0xffff-rWTCNT; //1count->64us, 200*400 cycle runtime = 64*i us
delayLoopCount=8000000/(i*64); //200*400:64*i=1*x:100 -> x=80000*100/(64*i)
}
}
/*****************************************
* *
* HM701Esp上GPIO口的配置初始化 *
* *
*****************************************/
void Port_Init(void)
{
rPDATA = 0x000;
rPCONA = 0xff;
rPDATB = 0x7ff;
rPCONB = 0x7cf;
rPDATC = 0xffff;
rPCONC = 0xff1fffff;
rPUPC =0x0;
rPDATD=0xff;
rPCOND= 0x9aaa;
rPUPD = 0x0;
rPDATE = 0x0ef;
rPCONE = 0x065a9;
rPCONE=(((rPCONE&0xfffcff)|0x100)|(0x1<<12));//设定bit4和bit6为蜂鸣器控制输出,吴改
rPUPE = 0x0;
rPDATF = 0x138;
rPCONF= 0x08055a;
rPUPF=0x3;
rPDATG=0x00;
rPCONG=0x0000;
rPUPG=0x00;
rSPUCR=0x0;
rEXTINT=0x22222222; // 所有的外部中断均为下降沿触发
}
/************************************************
* *
* 用串口构建的可同超级终端交互的函数集 *
* *
************************************************/
static int whichUart=0;
void Uart_Init(int mclk,int baud)
{
int i;
if(mclk==0)
mclk=MCLK;
rUFCON0=0x0; //FIFO disable
rUFCON1=0x0;
rUMCON0=0x0;
rUMCON1=0x0;
//UART0
rULCON0=0x3; //Normal,No parity,1 stop,8 bit
rUCON0=0x245; //rx=edge,tx=level,disable timeout int.,enable rx error int.,normal,interrupt or polling
rUBRDIV0=( (int)(mclk/16./baud + 0.5) -1 );
//UART1
rULCON1=0x3;
rUCON1=0x245;
rUBRDIV1=( (int)(mclk/16./baud + 0.5) -1 );
Uart1Enable;//串口1的输出与其他资源共用,所以在此处需要使能串口1
for(i=0;i<100;i++);
}
void Uart_Select(int ch)
{
whichUart=ch;
}
void Uart_TxEmpty(int ch)
{
if(ch==0)
while(!(rUTRSTAT0 & 0x4)); //wait until tx shifter is empty.
else
while(!(rUTRSTAT1 & 0x4)); //wait until tx shifter is empty.
}
char Uart_Getch(void)
{
if(whichUart==0)
{
while(!(rUTRSTAT0 & 0x1)); //Receive data read
return RdURXH0();
}
else
{
while(!(rUTRSTAT1 & 0x1)); //Receive data ready
return rURXH1;
}
}
char Uart_GetKey(void)
{
if(whichUart==0)
{
if(rUTRSTAT0 & 0x1) //Receive data ready
return RdURXH0();
else
return 0;
}
else
{
if(rUTRSTAT1 & 0x1) //Receive data ready
return rURXH1;
else
return 0;
}
}
void Uart_GetString(char *string)
{
char *string2=string;
char c;
while((c=Uart_Getch())!='\r')
{
if(c=='\b')
{
if( (int)string2 < (int)string )
{
Uart_Printf("\b \b");
string--;
}
}
else
{
*string++=c;
Uart_SendByte(c);
}
}
*string='\0';
Uart_SendByte('\n');
}
int Uart_GetIntNum(void)
{
char str[30];
char *string=str;
int base=10;
int minus=0;
int lastIndex;
int result=0;
int i;
Uart_GetString(string);
//Uart_Printf("You Input the Number string is :%s",string);
if(string[0]=='-')
{
minus=1;
string++;
}
if(string[0]=='0' && (string[1]=='x' || string[1]=='X'))
{
base=16;
string+=2;
}
lastIndex=strlen(string)-1;
if( string[lastIndex]=='h' || string[lastIndex]=='H' )
{
base=16;
string[lastIndex]=0;
lastIndex--;
}
if(base==10)
{
//result=atoi(string);
for(i=0;i<=lastIndex;i++)
{
if((string[i]>='0') && (string[i]<='9'))
result=(result * 10)+string[i]-'0';
}
result=minus ? (-1*result):result;
}
else
{
for(i=0;i<=lastIndex;i++)
{
if((string[i]>='a') && (string[i]<='f'))
result=(result<<4)+string[i]-'a'+10;
else if ((string[i]>='A') && (string[i]<='F'))
result=(result<<4)+string[i]-'A'+10;
else if ((string[i]>='0') && (string[i]<='9'))
result=(result<<4)+string[i]-'0';
}
result = minus ? (-1*result):result;
}
return result;
}
void Uart_SendByte(char data)
{
if(whichUart==0)
{
if(data=='\n')
{
while(!(rUTRSTAT0 & 0x2));
Delay(10); //because the slow response of hyper_terminal
WrUTXH0('\r');
}
while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
Delay(10);
WrUTXH0(data);
}
else
{
if(data=='\n')
{
while(!(rUTRSTAT1 & 0x2));
Delay(10); //because the slow response of hyper_terminal
rUTXH1='\r';
}
while(!(rUTRSTAT1 & 0x2)); //Wait until THR is empty.
Delay(10);
rUTXH1=data;
}
}
void Uart_SendString(char *pt)
{
while(*pt)
Uart_SendByte(*pt++);
}
//vsprintf()来自ARM运行时库,不用它的话会使代码减少许多
void Uart_Printf(char *fmt,...)
{
va_list ap;
char string[256];
va_start(ap,fmt);
vsprintf(string,fmt,ap);
Uart_SendString(string);
va_end(ap);
}
/************************************************
* *
* 利用WatchDog Timer 以一定的间隔测时间长 *
* 使用方法:先调Timer_Start *
* 后调Timer_Stop *
* *
************************************************/
void Timer_Start(int divider) //0:16us,1:32us 2:64us 3:128us
{
rWTCON=((MCLK/1000000-1)<<8)|(divider<<3);
rWTDAT=0xffff;
rWTCNT=0xffff;
// 1/16/(65+1),nRESET & interrupt disable
rWTCON=((MCLK/1000000-1)<<8)|(divider<<3)|(1<<5);
}
int Timer_Stop(void)
{
rWTCON=((MCLK/1000000-1)<<8);
return (0xffff-rWTCNT);
}
/************************************************
* *
* 简单的内存管理实例:使用时须先分配的后释放 *
* *
************************************************/
void * malloc(unsigned nbyte)
/*Very simple; Use malloc() & free() like Stack*/
{
void *returnPt=mallocPt;
mallocPt= (int *)mallocPt+nbyte/4+((nbyte%4)>0); //to align 4byte
if( (int)mallocPt > HEAPEND )
{
mallocPt=returnPt;
return NULL;
}
return returnPt;
}
void free(void *pt)
{
mallocPt=pt;
}
/************************************************
** **
** 定义CPU异常的简单处理函数 **
** 以便程序排错 **
** **
************************************************/
/**未定义指令异常**/
void HaltUndef(void)
{
Uart_Printf("Undefined instruction exception!!!\n");
while(1);
}
/**软中断异常**/
void HaltSwi(void)
{
Uart_Printf("SWI exception!!!\n");
while(1);
}
/**预取指异常**/
void HaltPabort(void)
{
Uart_Printf("Pabort exception!!!\n");
while(1);
}
/**数据访问异常**/
void HaltDabort(void)
{
Uart_Printf("Dabort exception!!!\n");
while(1);
}
/****/
void Isr_Init(void)
{
pISR_UNDEF=(unsigned)HaltUndef;
pISR_SWI =(unsigned)HaltSwi;
pISR_PABORT=(unsigned)HaltPabort;
pISR_DABORT=(unsigned)HaltDabort;
rINTCON=0x5; // Non-vectored,IRQ enable,FIQ disable
rINTMOD=0x0; // All=IRQ mode
rINTMSK=BIT_GLOBAL; // All interrupt is masked.
}
/************************************************
* *
* 库初始化函数 *
* 要使用库函数必须调用库初始化 *
* *
************************************************/
void _44blib_init(void)
{
rSYSCFG=CACHECFG;
// __rt_lib_init(); //for ADS 1.0
Port_Init();
Isr_Init();
Uart_Init(0,115200); //串口0、1初始化
Uart_Select(1);
Delay(0); //校准延时循环值
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -