📄 main.c
字号:
/*******************************************************************************
* FILENAME : MAIN.C
* AUTHOR : rentt
* HISTORY : 2007-11-6 19:40 Modify by rtt
* 2007-10-1 19:39 Create by rtt
* DESC : iPT功能测试程序(K线,CAN,J1850,PWM...)
* COPYRIGHT : AUTOSCAN Co.,Ltd. http//:www.autoscan.com.cn
*******************************************************************************/
#include <hidef.h> /* common defines and macros */
#include <mc9s12dj64.h> /* derivative information */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#pragma LINK_INFO DERIVATIVE "mc9s12dj64"
#include "main.h" // main header
//******************************************************************************
const byte sendbytebuf[]={0,1,2,3,4,5,6,7};
/*******************************************************************************
* FUCNAME : PLL_Init
* DESC : 初始化PLL振荡器,外部有源晶振8MHz,内部倍频至24MHz
* INPUT : void
* RETURN : void
*******************************************************************************/
void PLL_Init(void)
{
CLKSEL =0;
PLLCTL_PLLON = 0;
SYNR = 2;
REFDV = 0;
PLLCTL = 0x70; // 8MHZ to 24MHZ
__NOP__();
__NOP__();
while(!CRGFLG_LOCK);
CLKSEL_PLLSEL = 1; // Select clock source from PLL
}
/*******************************************************************************
* FUCNAME : RTI_Init
* DESC : 初始化实时时钟1ms周期
* INPUT : void
* RETURN : void
*******************************************************************************/
void RTI_Init(void)
{
RTICTL = 0x17; // set RTI prescaler:8mhz-->1.024ms
CLKSEL_RTIWAI=0;
CRGINT_RTIE = 1; // enable RTI interrupts
}
//TSCR2_PR:Prescale Factor =(0:1),(1:2),(2:4),(3:8),(4:16),(5:32),(6:64),(7:128);
static void TimeInit(void)
{
// timer enable, freeze while BDM
//TSCR1 = TSCR1_TEN_MASK | TSCR1_TSFRZ_MASK;
}
/*******************************************************************************
* FUCNAME : PORT_Init
* DESC : 初始化端口IO
* INPUT : void
* RETURN : void
*******************************************************************************/
static void PORT_Init(void)
{
//ADC
ATD0DIEN = 0x60; // AD6,AD5
// ATD0CTL2 = 0x00; // Close A/D
//PORTS(7):PTS,PTIS,DDRS,RDRS,PERS,PPSS,WOMS.
PTS = 0x0F;
DDRS = 0x0A;
PPSS = 0x00;
PERS = 0x0F;
WOMS = 0x00;
//spi0 in ports4~7,can in portj6~7
MODRR = 0x03;
//
PTM = 0x3E;
DDRM = 0x3E;
PPSM = 0x01; //Polarity Select Register
WOMM = 0x00;
//PORTP():
PTP = 0xEF;
DDRP = 0xEF;
PERP = 0x00;
//PORTT(6):PTT,PTIT,DDRT,RDRT,PERT,PPST.
PTT = 0xFE;
DDRT = 0xFE; //
PERT = 0x00;
TIOS = 0xFA; //0:in,1~7:out;
//
PORTAB =0xFFFF; //rece(15:12),kcom,k1~kb(11:0)
DDRAB = 0xFFFF;
//
PORTE = 0xFF;
DDRE = 0xFF;
}
/*******************************************************************************
* 延时函数
*/
void Delay_100us(word us) //1ms:24MHZ bus
{
word cnt;
//
for(;us;us--)
for(cnt=720;cnt;cnt--);
}
//
void Delay_1ms(word us) //1ms:24MHZ bus
{
word cnt;
//
for(;us;us--)
for(cnt=7200;cnt;cnt--);
}
void Delay_MDC1ms(word ms)
{
byte MCCTL_back;
//
if(ms==0)return;
MCCTL_back=MCCTL;
MCCTL = (MCCTL_MODMC_MASK | MCCTL_MCEN_MASK | 0x03); //ECLK=24MHz
//
while(ms){
if(ms>40)
{MCCNT = 0xEA60;ms-=40;}
else
{MCCNT = ms*1500;ms=0;}
MCCTL_FLMC=1;
MCFLG_MCZF=1;
for(;MCFLG_MCZF==0;)__NOP__();
}
MCFLG_MCZF=1;
MCCTL=MCCTL_back;
}
void Delay_MDC1us(dword us)
{
byte MCCTL_back;
//
MCCTL_back=MCCTL;
MCCTL = (MCCTL_MODMC_MASK | MCCTL_MCEN_MASK | 0x00); //ECLK=24MHz
//
while(us){
if(us>100)
{MCCNT = 2400;us-=100;}
else
{MCCNT = (word)us*24;us=0;}
MCCTL_FLMC=1;
MCFLG_MCZF=1;
for(;MCFLG_MCZF==0;)__NOP__();
}
MCFLG_MCZF=1;
MCCTL=MCCTL_back;
}
/*******************************************************************************
* FUCNAME : PWM_Init
* DESC : 初始化PWM模块
* INPUT : void
* RETURN : void
*******************************************************************************/
void PWM_Init(byte PCKA)
{
PWMCTL =0; //
PWMPRCLK_PCKA=PCKA;//0; // PWM时钟源A预分频参数E~E/128
}
/*******************************************************************************
* FUCNAME : PWM3_153K
* DESC : PWM3输出153.6KHz时钟, 155=24000/153.6-1
* INPUT : PER, 周期参数
DTY, 占空比高电平参数(为0时关闭PWM)
* RETURN : void
*******************************************************************************/
void PWM3_153K(byte PER,byte DTY)
{
word temp;
//
if(DTY){
PWME_PWME3 =0;
// PWMCTL =0;
// PWMPRCLK_PCKA=0;
//
PWMPER3 =PER;
temp=PER*DTY+40;
// PWMDTY3 =(byte)(temp/100);
PWMDTY3 =DTY;
PWME_PWME3 =1;
}
else {
PWME_PWME3 = 0;
PTP_PTP3 = 0; // ECLK_PWM = 0;
}
}
void PWM0_Clk(byte PER,byte DTY)
{
word temp;
//
if(DTY){
PWME_PWME0 =0;
// PWMCTL =0;
// PWMPRCLK_PCKA=0;
//
PWMPER0 =PER;
temp=PER*DTY+40;
// PWMDTY3 =(byte)(temp/100);
PWMDTY0 =DTY;
PWME_PWME0 =1;
}
else {
PWME_PWME0 = 0;
PTP_PTP0 = 0; // ECLK_PWM = 0;
}
}
#define PWM_OPEN() {PORTB_BIT4 = 0;PORTB_BIT3 = 1;} // OPEN PWM
#define PWM_CLOSE() {PORTB_BIT4 = 1;} // CLOSE
#define VPW_OPEN() {PORTB_BIT4 = 1;PORTB_BIT3 = 0;} // OPEN VPW
#define VPW_CLOSE() {PORTB_BIT3 = 1;}
#define ALOOP_OPEN() DDRP_DDRP4=0;
#define ALOOP_CLOSE() DDRP_DDRP4=1;
#define VPW4X PTP_PTP4
#define VPW4X_OPEN() {VPW4X = 1; DLCBCR2_RX4XE = 1;}
#define VPW4X_CLOSE() {VPW4X = 0; DLCBCR2_RX4XE = 0;}
#define BDLC_EOF 0x04 // Received an end of frame
#define BDLC_RXIRF 0x08 // Received IFR byte
#define BDLC_RDRF 0x0c // BDLC Rx data register full
#define BDLC_TDRE 0x10 // BDLC Tx data register empty
#define BDLC_LOA 0x14 // Loss of arbitration
#define BDLC_CRC 0x18 // Cyclical redundancy check error
#define BDLC_SYMBOL 0x1c // Symbol invalid
#define BDLC_WAKE 0x20 // Wakeup
void J1850_PwmTest(void)
{
PORTB_BIT4 = 0; // PWM EN = 1 open pwm
PORTB_BIT3 = 1; // VPW EN = 0 close vpw
PWM0_Clk(155,(155-1)/2); // 155 = 153.6k
Delay_1ms(2000);
PWM0_Clk(0,0);
}
void J1850_VpwTest(void)
{
int i;
byte tempf, tempf2;
printf("\n J1850_VpwTest");
VPW_OPEN();
DLCBARD_RXPOL = 0; // 1:接收正极性,默认 0:接收负极性(cpld反相)
//确定时钟源,复位后只允许写一次
DLCBRSR = 23; // 1MHz=ECLOCK/(1+23)
DLCBCR2 = 0x00; // DLoop=ALoop=0
DLCBCR1 = 0x80; // CLKS=1:1.048576MHz,0:1MHz
ALOOP_CLOSE();
VPW4X_CLOSE();
DLCBCR2_DLOOP = 0;
DLCSCR_BDLCE =1; // BDLC Enable
for (i=0;i<8;i++){
DLCBDR = sendbytebuf[i];
Delay_1ms(5);
}
}
/*******************************************************************************
* FUCNAME : ATD_Read
* DESC : AD单次读取,查询方式
* INPUT : channel, 通道号
* RETURN : 12位AD值
*******************************************************************************/
word ATD_Read(byte channel)
{
ATD_EN(); // 打开AD
ATD0CTL3 = ATD0CTL3_S1C_MASK; //one
channel = ATD0CTL5_DJM_MASK + (channel & ATD0CTL5_Cx_MASK); //2006-7-25 15:24
ATD0CTL5 = channel;
while(!ATD0STAT0_SCF);
ATD_DIS(); // 关闭AD
return (ATD0DR0);
}
/*******************************************************************************
* 数字电位器X931X读写,用于K线比较电压生成,
* X_CS PT6
* X_INC PT5
* X_U/D PT4
___
|
| |
| | R1=3.9K
| |
|
| |/ RS=0~10K(X9318)
|/|----> V
/| |
|
| |
| | R2=0.1K
| |
|
---
-
* X9318为0~10K 100级可调,当RS=0时,V=0.3V; RS=10K时,V=8.65V
*/
#define Delay Delay_MDC1ms
#define X931X_LEVEL 100 // 100等级
#define X_CS(a) PTT = (PTT&~0x40)|((a<<6)&0x40)
#define X_INC(a) PTT = (PTT&~0x20)|((a<<5)&0x20)
#define X_UD(a) PTT = (PTT&~0x10)|((a<<4)&0x10)
/*******************************************************************************
* 向上调整一级
*/
void X931X_Up(void)
{
X_CS(0); // select X9313
X_UD(1); // up drection
X_INC(1);
Delay(1);
X_INC(0);
Delay(1);
}
/*******************************************************************************
* 向下调整一级
*/
void X931X_Down(void)
{
X_CS(0); // select X9313
X_UD(0); // down drection
X_INC(1);
Delay(1);
X_INC(0);
Delay(1);
}
/*******************************************************************************
* 将当前值存储(修改过值后如果不存储掉电将不能保存)
*/
void X931X_Store(void)
{
X_INC(1);
X_CS(0);
Delay(1);
X_CS(1);
Delay(1);
}
/*******************************************************************************
* 休眠(电阻值保持)
*/
void X931X_Standby(void)
{
X_CS(1);
Delay(1);
}
/*******************************************************************************
* 设置X931X的值(0~99)
*/
void X931X_Set(char val)
{
char i;
for (i=0; i<X931X_LEVEL; i++) {
X931X_Down();
Delay(1);
}
for (i=0; i<val; i++) {
X931X_Up();
Delay(1);
}
}
//-----------------------------------------------------------------------------
/*******************************************************************************
* FUCNAME : SCI1_Init
* DESC : 串口1初始化,查询方式,波特率=115200
* INPUT : void
* RETURN : void
*******************************************************************************/
void SCI1_Init(void)
{
SCI1CR2_SCTIE=0;
//
SCI1BD = (word)(ECLOCK / factor/ 57600);
SCI1CR2 = SCI1CR2_TE_MASK | SCI1CR2_RE_MASK;
}
void SCI1_Putc(char ch)
{
while(!(SCI1SR1 & SCI1SR1_TDRE_MASK)); // 发送保持器空
SCI1DRL = ch;
while(SCI1SR1 & SCI1SR1_TC_MASK);
}
/*******************************************************************************
* FUCNAME : SCI0_Init
* DESC : 串口0初始化,查询方式,波特率=115200
* INPUT : void
* RETURN : void
*******************************************************************************/
void SCI0_Init(void)
{
SCI0CR2_SCTIE=0;
//
SCI0BD = (word)(ECLOCK / factor/ 115200);
SCI0CR2 = SCI0CR2_TE_MASK | SCI0CR2_RE_MASK;
}
char SCI0_Getc(void)
{
char ch;
while(!(SCI0SR1 & SCI0SR1_RDRF_MASK)); // 接收数据就绪
ch = SCI0DRL;
return ch;
}
void SCI0_Putc(char ch)
{
while(!(SCI0SR1 & SCI0SR1_TDRE_MASK)); // 发送保持器空
SCI0DRL = ch;
while(SCI0SR1 & SCI0SR1_TC_MASK);
}
void SCI0_Puts(char *str)
{
while( *str != '\0') {
SCI0_Putc(*str);
str ++;
}
}
/*******************************************************************************
* 重定义系统printf中用到的输出字符和获取字符,之后就可以使用printf了
*/
void TERMIO_PutChar(char ch);
void TERMIO_PutChar(char ch){
SCI0_Putc(ch);
}
char TERMIO_GetChar(void);
char TERMIO_GetChar(void){
return SCI0_Getc();
}
/*******************************************************************************
* 串口0接收中断
*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 20 void SCI0Rxd_ISR(void)
{
}
/*******************************************************************************
* K线端口操作宏定义
*/
// K1电压设置(0=NO PUP; 1=5V; 2=12V; 3=NO PUP)
#define SET_VDDK1(v) {PORTA &= 0xfc; PORTA |= v&0x03;}
// K2电压设置(0=NO PUP; 1=5V; 2=12V; 3=NO PUP)
#define SET_VDDK2(v) {PORTA &= 0xf3; PORTA |= (v&0x03)<<2;}
// K1端口选择(0~15:K1~K16)
#define SET_K1PORT(p) {PORTA &= 0x0f; PORTA |= (p&0x0f)<<4;}
// K1逻辑选择(0=负; 1=正)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -