📄 mcudriver.c
字号:
/*==================================================*
* 文件: EMMP3_1264Driver.c
* 功能: 板上各个功能模块的驱动.c文件
* 作者: 从国涛 常皓
* 开始日期:2005/1/20
* 结束日期:2005/4/5
* 备注:
**==================================================*/
/*******************SCI********************************/
//==================================================
// 日期 | 人员 | 变更细节
// ****** | ****** | *************
// 2004/3/9 | 常皓 | 初始化程序
// 2004/3/13 | 常皓 | 修改程序注释
//==================================================
#include "MCUDriver.h"
#include "math.h"
/*==================================================*
* 函数: SCI_Init
* 功能: SCI的初始化
* 作者: 常皓
* 参数: nSCINo unsigned int : SCI端口号
* dwBaud unsigned long: 波特率
* ucNineBits unsigned char : 传送类型是9bit还是8bit
* 返回值:
* 备注:
**==================================================*/
unsigned int SCI_Init(unsigned int nSCINo,
unsigned long dwBaud,
unsigned char ucNineBits){
int nX;
unsigned long dwTmp;
/* 计算波特率、设定波特率寄存器 */
dwTmp = 16UL * dwBaud;
nX = (int)(BUSCLK/dwTmp); //不需要减一就可以 (int)(FOSC/dwTmp) - 1
if((nX > 8192) || (nX < 0))
{
return 1; // 不能获得波特率
}
// SCI0
if(nSCINo == SCINO_0){
SCI0BD = nX; //波特率的设定
/* SCI控制寄存器一的设定 */
// SCI0CR1 = 0x02; // 有奇偶校验
//SCI0CR1 = 0x80; // 无奇偶校验,自测模式
SCI0CR1 = 0x00; // 无奇偶校验,普通模式
SCI0CR1_M = ucNineBits?1:0; // 8- or 9-bit的设定
/* SCI控制寄存器二的设定 */
SCI0CR2 = 0x2c; //允许发送,允许接受中断,屏蔽发送空中断,屏蔽发送完成中断,屏蔽接受器空闲中断
dwTmp = SCI0DRH; //清空数据寄存器高位
dwTmp = SCI0DRL; //清空数据寄存器低位
dwTmp = SCI0SR1; //清空SCI状态寄存器1
dwTmp = SCI0SR2; //清空SCI状态寄存器2
}
// SCI1
else if(nSCINo == SCINO_1){
SCI1BD = nX; //波特率的设定
/* SCI控制寄存器一的设定 */
SCI1CR1 = 0x00; // 有奇偶校验
SCI1CR1_M = ucNineBits?1:0; // 8- or 9-bit的设定
/* SCI控制寄存器二的设定 */
SCI1CR2 = 0x2c; //允许发送,允许接受中断,屏蔽发送空中断,屏蔽发送完成中断,屏蔽接受器空闲中断
dwTmp = SCI1DRH; //清空数据寄存器高位
dwTmp = SCI1DRL; //清空数据寄存器低位
dwTmp = SCI1SR1; //清空SCI状态寄存器1
dwTmp = SCI1SR2; //清空SCI状态寄存器2
}
else {
return 1; /* 初始化失败 */
}
return 0;
}
/*==================================================*
* 函数: SCI_PutByte
* 功能: 发送一个byte值
* 作者: 常皓
* 参数: nSCINo unsigned int : SCI端口号
* ucValue unsigned char: 发送数据
* 返回值:
* 备注:
**==================================================*/
void SCI_PutByte(unsigned int nSCINo, unsigned char ucValue){
if(nSCINo == SCINO_0) {
while(!SCI0SR1_TDRE);
SCI0DRL = ucValue;
while(!SCI0SR1_TC);
}
else if(nSCINo == SCINO_1){
while(!SCI1SR1_TDRE);
SCI1DRL = ucValue;
while(!SCI1SR1_TC);
}
}
/*==================================================*
* 函数: SCI_GetByte
* 功能: 取得一个byte值
* 作者: 常皓
* 参数: nSCINo unsigned int : SCI端口号
* 返回值: unsigned char : 取得一个byte值
* 备注:
**==================================================*/
unsigned char SCI_GetByte(unsigned int nSCINo){
if(nSCINo == SCINO_0){
return SCI0DRL;
}
else if (nSCINo == SCINO_1){
return SCI1DRL;
}
}
/*******************SCI********************************/
/**********************IRQ****************************/
void IRQEn(){ /*IRQ中断使能*/
INTCR_IRQE=1;
INTCR_IRQEN=1;
}
void IRQDis(){ /*IRQ中断禁止*/
INTCR_IRQEN=0;
}
/***********************EEPROM****************************/
/*==================================================*
* 函数: EEPROMInit
* 功能: EEPROM 初始化程序
* 作者: Cong Guotao
* 参数:
* 返回值: -1:初始化失败;0:初始化成功
* 备注:
**==================================================*/
char EEPROMInit(void){
float Tbus,pclk;
uchar ediv;
Tbus=1000000/BUSCLK;
if(Tbus>1)return -1; //返回-1表示初始化失败
if(OSCCLK>12800000){
pclk=OSCCLK/8/1000000;
ECLKDIV_PRDIV8=1;
}
else pclk=OSCCLK/1000000;
ediv=pclk*(5+Tbus);
ECLKDIV|=ediv;
EPROT=0x88;
ESTAT = ESTAT | (ESTAT_PVIOL|ESTAT_ACCERR);// Clear any errors
return 0;
}
/*==================================================*
* 函数: EEPROM_Write_Word
* 功能: 向EEPROM中写一个字,即2Byte .
* 作者: Cong Guotao
* 参数: far_address unsigned int * :EEPROM 地址
* data unsigned int : 要写的数据
* 返回值: -1:为奇地址,-2:访问出错,-3:为保护区,写错误;0:写成功。
* 备注:
**==================================================*/
char EEPROM_Write_Word(unsigned int *far far_address,
unsigned int data)
{
unsigned int* address;
address = (unsigned int*)far_address;
ESTAT = (ESTAT_ACCERR | ESTAT_PVIOL); // clear errors
if((unsigned int)address & 0x0001) {return -1;} // Aligned word?
// if(*far_address != 0xFFFF) {return Flash_Not_Erased;} // Is it erased?
(*address) = data; // Store desired data to address being programmed
ECMD = 0x20; // Store programming command in ECMD
ESTAT=0x80; //program start
if (ESTAT_ACCERR) {return -2;}
if (ESTAT_PVIOL) {return -3;}
while(!ESTAT_CBEIF); //wait end
return 0;
}
/*==================================================*
* 函数: EEPROM_Erase_Sector
* 功能: 擦除一个扇区(4Byte)
* 作者: Cong Guotao
* 参数: far_address unsigned int *far: EEPROM 中的数据地址
* 返回值: unsigned char : 取得一个byte数据
* 备注:
**==================================================*/
char EEPROM_Erase_Sector(unsigned int *far far_address)
{
unsigned int* address;
address = (unsigned int*)far_address;
if((unsigned int)address & 0x0001) {return -1;} // Aligned word?
ESTAT = (ESTAT_ACCERR | ESTAT_PVIOL); // clear errors
(*address) = 0xFFFF; // Dummy store to page to be erased
ECMD=0x40; // Store erase command in ECMD
ESTAT=0x80; //erase start
if (ESTAT_ACCERR) {return -2;}
if (ESTAT_PVIOL) {return -3;}
while(!ESTAT_CBEIF); //wait end
return 0;
}
/*==================================================*
* 函数: EEPROM_Erase_Block
* 功能: 擦除一段 EEROM
* 作者: Cong Guotao
* 参数: far_address uint * : EEPROM 的目标地址
* count unsigned int : 扇区个数(2Word)
* 返回值: -1,-2:擦失败 ;0:擦成功。
* 备注:
**==================================================*/
char EEPROM_Erase_Block(unsigned int *far far_address,\
unsigned int count)
{
unsigned long i;
signed char ret_val;
for (i = 0;i<count;i++)
{
ret_val = EEPROM_Erase_Sector(far_address++);
far_address++;
if (ret_val == -1) {return -1;}
if (ret_val == -2) {return -2;}
}
return 0;
}
/*==================================================*
* 函数: EEPROM_Write_Block
* 功能: 写一段 EEROM
* 作者: Cong Guotao
* 参数: address_source unsigned int * : 要搬运的数据块源地址
* far_address_destination uint * : EEPROM 的目标地址
* count unsigned int : 数据个数(Word)
* 返回值: -1,-2:写失败 ;0:写成功。
* 备注:
**==================================================*/
char EEPROM_Write_Block(unsigned int *far address_source,\
unsigned int *far far_address_destination,\
unsigned int count)
{
unsigned long i;
signed char ret_val;
for (i = 0;i<count;i++)
{
ret_val = EEPROM_Write_Word(far_address_destination++, *address_source++);
if (ret_val == -1) {return -1;}
if (ret_val == -2) {return -2;}
}
return 0;
}
/*==================================================*
* 函数: EEPROM_Read_Block ????
* 功能: 读出一段 EEROM 的内容
* 作者: Cong Guotao
* 参数: address_source unsigned int * : EEPROM 中的数据块源地址
* far_address_destination uint * : 目标地址
* count unsigned int : 数据个数(Word)
* 返回值:
* 备注:
**==================================================*/
void EEPROM_Read_Block(unsigned int *far address_source,\
unsigned int *far far_address_destination,\
unsigned int count)
{
uint i;
unsigned int* address;
address = (unsigned int*)far_address_destination;
for (i=0;i<count;i++){
* address++ = * address_source++ ;
}
}
/*********************PLL*******************************/
/*==================================================*
* 函数: PLLInit
* 功能: 总线时钟采用锁相环倍频至25M
* 作者: Cong Guotao
* 参数:
* 返回值:
* 备注:
**==================================================*/
void PLLInit(void){
//SYNR=0x18;
SYNR=39;
REFDV=0x0f;
//while((CRGFLG!=0x5c)&&(CRGFLG!=0x1c));
while(CRGFLG_LOCK == 0);
CLKSEL=0x80;
PLLCTL_AUTO=1;
}
/*********************RTI********************************/
/*==================================================*
* 函数: RTIInit
* 功能: 开系统实时中断,间隔1.024ms中断一次
* 作者: Cong Guotao
* 参数:
* 返回值:
* 备注:
**==================================================*/
void RTIInit(void){
// RTICTL=0x50; //osc been driven is 1.024ms with RTICTL=0x50;
//RTICTL=0x59; //10.24ms
RTICTL=0x52; //3.072ms
// RTICTL=0x79; //40.96ms
CRGINT_RTIE=1; //enable RTI
}
/*************Modulus Down Counter************************/
/*==================================================*
* 函数: MDCounterInit
* 功能: 允许Modulus Down Counter 计数器,0.01秒中断一次
* 作者: Cong Guotao
* 参数:
* 返回值:
* 备注:总线16分频,溢出后自动置初值,中断使能,每个记数0。64us
**==================================================*/
void MDCounterInit(void){
//MCCTL=0xc7;
MCCTL = 0xc3;
MCCNT = BUSCLK/16/10000; //10ms
// MCCNT=0x3aa; //0.6ms 断一次
}
/*============================================
OpenMDC
打开定时器模块
==============================================*/
void OpenMDC(void) {
MCCTL_MCEN = 1;
MCCNT = BUSCLK/16/10000; //10ms;
//MCCNT = 0x30d; //500us;
//18750; //12MS
//3125; //2ms
MCCTL_FLMC = 1;
//MCCNT=0x3d09; //10ms
//MCCNT=0x30d4; //8ms 断一次
}
/*============================================
CloseMDC
打开定时器模块
==============================================*/
void CloseMDC(void) {
MCCTL_MCEN = 0;
}
/*****************GPIO****************************/
/*==================================================*
* 函数: GPIOInit
* 功能: I/O方向初始化
* 作者: Cong Guotao
* 参数:
* 返回值:
* 备注:
**==================================================*/
void GPIOInit(void ){
}
/*========================================================//
函数:PORTINIT
功能: pb0-pb7--IR_EN0-7,
作者:冯瑜
参数:
返回值:
备注:检测回的口初始化状态为低电平
/==========================================================*/
void PORTINIT(void){
/*
//检测
DDRT_DDRT4=0; //设置PT4为输入状态 ,start
DDRB =DDRB_BIT0_MASK|DDRB_BIT1_MASK|DDRB_BIT2_MASK|DDRB_BIT3_MASK;//pb0-pb3--ID1_EN1-4输出
DDRE=DDRE_BIT3_MASK|DDRE_BIT2_MASK; //LD2_en1-2
DDRA=DDRA_BIT1_MASK; //Ld2_en
//////////////
//使用下面8个
DDRJ=DDRJ_DDRJ6_MASK|DDRJ_DDRJ7_MASK; //Ld3_en设为输出状态
DDRM=DDRM_DDRM0_MASK|DDRM_DDRM1_MASK|DDRM_DDRM2_MASK|DDRM_DDRM3_MASK|DDRM_DDRM4_MASK|DDRM_DDRM5_MASK; //m4,m5 输出
//发射管不使能
PORTB=PORTB_BIT0_MASK|PORTB_BIT1_MASK|PORTB_BIT2_MASK|PORTB_BIT3_MASK;
PORTE=PORTE_BIT3_MASK|PORTE_BIT2_MASK;
PORTA=PORTA_BIT1_MASK;
PTJ=PTJ_PTJ6_MASK|PTJ_PTJ7_MASK;
PTM=PTM_PTM0_MASK|PTM_PTM1_MASK|PTM_PTM2_MASK|PTM_PTM3_MASK|PTM_PTM4_MASK|PTM_PTM5_MASK;
*/
/* DDRA =0;//DDRA_BIT_BITNUM;
DDRM_DDRM0=0;
DDRM_DDRM1=0;
DDRM_DDRM2=0;
DDRM_DDRM3=0;
PORTA=0;//PORTA_BIT_BITNUM; ?
PTM&=PTM_PTM7_MASK|PTM_PTM6_MASK|PTM_PTM5_MASK|PTM_PTM4_MASK;//0xF0;
*/
//drive口
DDRT|=DDRT_DDRT5_MASK; //D2 为输出状态
DDRP|=DDRP_DDRP1_MASK|DDRP_DDRP4_MASK|DDRP_DDRP5_MASK; //D1 ,in2
DDRT_DDRT6=1; //D1 output
PTP_PTP1=1;
PTT_PTT6=0;//D1 enble
PTT_PTT5=0; //D2输出不使能
PTP_PTP4=0; //禁止portp4,5---in2
PTP_PTP5=0;
//ATD0DIEN=0x17;
}
/*==================================================
ATDInit
AD模块初始化 Tsum=12ATDclk
====================================================*/
void ATDInit(void){
ATD0CTL2 = 0xc2;//0xc2; //普通模式,转换完毕中断使能,快速清除中断标志
ATD0CTL3 = 0x09;//0x19; //00011001顺序转换长度为3 ,调试时保留,no fifl
ATD0CTL4 = 0x80;//0x80 ATDclk = 0.08us //实测时间 2.48us/次 //总线25M
//实测时间 1.57us/次 //总线40M
//0x81 ATDclk = 0.16us //实测时间 2.48us/次
//0x82 ATDclk = 0.24us //实测时间 4.54us/次
//0x84 ATDclk = 0.4us
//0X85 ATDclk = 0.48us //实测时间 7.76us/次
//0x86, ATDclk = 0.56us //实测时间 8.73us/次
//0x98;//转换结果为8bit,转换时钟为2us,Tsum=12ATDclk
//ATD0TEST1 = 0x01; //测试模式
//ATD0CTL5 = 0x13;//转换结果左对齐,无符号;从3口连续顺序转换 ,启动AD转换
//ATD0DIEN=0x04;//ATD0DIEN_BIT2_MASK|ATD0DIEN_BIT1_MASK |ATD0DIEN_BIT0_MASK ; // AD使能 ATTDDRXH结果寄存器 ATD0DINEN
}
/*========================================================//
函数:PWMINIT
功能:pwm2,3组成16位的in1产生10khz,用于驱动电机;(pwm0产生38khz的脉冲),pwm6,7-steer200hz
作者:冯瑜
参数:
返回值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -