|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2009-6-1 10:41:16
|
显示全部楼层
#include <msp430x14x.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define comm 150
///// 管脚定义/////
#define CS_1 P3OUT |=0x01;
#define CS_0 P3OUT &=~0x01;
#define DOUT_1 P3OUT |=0x02;
#define DOUT_0 P3OUT &=~0x02;
#define SCLK_1 P3OUT |=0x08;
#define SCLK_0 P3OUT &=~0x08;
#define DIN_IN ((P3IN & 0x04)==0x04);
static unsigned char comm_data0[comm];
static unsigned char comm_data1[comm];
static unsigned int semiseconde;//,test1,test2;///half_sseconde,,seconde
//////port ini/////
void init_ioport(void)
{
P1DIR=0Xff; //输出
P1IE=0X00; //禁止中断
P1SEL=0X00; // IO端口
P1OUT=0X00; // 初始值为0 为青云液晶的数据口
P2DIR=0X00; //输入
P2SEL=0X00; //IO端口
P2IE=0X00; //禁止中断
P3DIR=0X7b; //p3.7,p3.2为输入, 其他为输出
P3SEL=0Xc0; //p3.6 p3.7 用作232 spi 通讯,其他作为IO端口
P4DIR=0XFF; //输出
P4SEL=0X00; //IO端口
P4OUT=0X00; //端口初始值
P5DIR=0XFF; //输出
P5SEL=0X00; //IO端口
P6OUT=0X00; //端口初始值
P6DIR=0XFC; //p6.0 ,p6.1 输入,其他输出
P6SEL=0X55; //p6.0, p6.1 用作模数转换输入,其他输出
}
//////end/////////
//////timer_A ini/////
void init_timerA(void)
{
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 &=~CCIE; //中断位为0,表示中断禁止
TAR=0X0000; //16位计数器内容,执行计数单元
CCR0=0; //定时数据 调试用
TACTL = TASSEL_2 + MC_1; //选择系统主时钟SMCLK,增计数模式,计数器计数到CCR0,再清零计数
}
//////end////////////
//////timer_B ini/////
void init_timerB(void)
{
TBCTL=MC_0; //停止模式,用于定时器暂停
TBCTL=CNTL_0; //16位,最大计数值为0FFFFH
TBCCTL0 &=~CCIE; //中断位为0,表示中断禁止
TBR=0X0000; //16位计数器内容,定时器得计数值存放单元
TBCTL=TBSSEL_2+MC_1; // 择系统主时钟SMCLK,增计数模式
}
//////end_timer_B//////
/////ADC ini ////////
void init_ADC(void)
{
ADC12CTL0 &= ~ENC; //模块处于初始状态,不能启动AD转换
ADC12CTL0=SHT0_8+MSC+ADC12ON; //890 n=64,采样周期=4*t*n,第一次转换由SHI上升沿触发定时器,打开ADC内核
ADC12CTL1=SHP+CONSEQ_2+ADC12SSEL_2; // 采样信号源自采样定时器,单通道多次转换模式,ADC12内核时钟是MCLK//?????????
ADC12MCTL0=SREF_2; //通道0参考电压V+选外部,V-选地,选择模拟输入通道0
ADC12MCTL1=SREF_2+INCH_1; //通道1参考电压V+选外部,V-选地,选择模拟输入通道1
ADC12IE=0X0000; //禁止ADC中断
}
/////end adc ini ///////////
/////UART1 ini//////
void init_UART1(void)
{
ME2 = UTXE1 + URXE1; // 允许USART1 异步串行工作
UCTL1 &=~SWRST; // 允许USART1模块工作
UCTL1 &=~SYNC; // USART1异步模式UART
UCTL1 |= CHAR; // 字符长度为为8位
UTCTL1 |=SSEL1;//0;//1; // 波特率发生器时钟选择SMCLK,8M
UBR01 = 0xa0;//41; // 32k/9600 - 0003 8M/9600 341 8M/19200
UBR11 = 0x01;//03; // 3.41 833.333 416.6667
UMCTL1 = 0xdb;//4a; // 32k/9600 - 4A 8M/9600 91 4A
//UTCTL1 |=SSEL0; // 波特率发生器时钟选择ACLK
}
/////end init_UART//////////
/////UART1 ini//////
void init_UART0(void)
{
ME1 |=UTXE0 + URXE0;// USPIE0; // 允许USART0 同步串行工作
UCTL0 &=~SWRST; // 允许USART0模块工作
UCTL0 |=SYNC; // USART0同步模式SPI
UCTL0 |= CHAR; // 字符长度为为8位
UCTL0 |=MM; //SPI主机模式
// UTCTL0 |=SSEL1; //
// UTCTL0 |=STC; //
UTCTL0=CKPH+CKPL+SSEL1+STC;//波特率发生器时钟选择SMCLK,8M,3线模式,STE在主从机模式中不起作用
//下降沿输出,数据在上升沿所存,UCLK延迟半个周期
UBR00 = 0x3b;//41 // 波特率为14K
UBR10 = 0x02;//03 // 571.43
UMCTL0 = 0x4A;//91 //
}
/////end init_UART//////////
////delay ms///// 内循环10次延时时间是11微秒,加上外部循环语句12.8微秒
///delay(1)延时12.8微秒
delay1(unsigned char time_ms)
{unsigned char i;
unsigned int j;
for(j=0;j<time_ms;j++)
{
for(i=0;i<8;i++);//10次延时12.8微秒,1次11.2微秒
}
}
////end/////
void delay (signed int length) 延时5.9微秒
{
while (length >0)
length--;
}
///////SPI 写命令给16350 /////address,value
void write16350()//(unsigned char camm_data1[0] ,unsigned char comm_data1[1])
{
unsigned char i,temp;
// temp=comm_data1[0] | 0x80;
temp=0xb7;
SCLK_1;
delay(1);
CS_1;
delay(1);
CS_0;
delay(1);
for(i=0;i<8;i++)
{
SCLK_0;
if((temp & 0x80)==0x80)
{
DOUT_1;
}
else
{
DOUT_0;
}
delay(1);
SCLK_1;
delay(1);
temp=temp<<1;
}
temp=comm_data1[1];
temp=0x0a;
for(i=0;i<8;i++)
{
SCLK_0;
if((temp & 0x80)==0x80)
{
DOUT_1;
}
else
{
DOUT_0;
}
delay(1);
SCLK_1;
delay(1);
temp=temp<<1;
}
CS_1;
delay(4000);
delay(4000);
delay(4000);
}
/////// end ///////
/////
void read16350()
{
unsigned char i,j,temp,temp1;
unsigned char receivedata=0;
for(j=0;j<2;j++)
{
temp=0x38;//38;//comm_data1[j];
SCLK_1;
delay(1);//(1);
CS_1;
delay(1);
CS_0;
delay(1);
for(i=0;i<8;i++)
{
SCLK_0;
//_NOP();
if((temp & 0x80)==0x80)
{
DOUT_1;
}
else
{
DOUT_0;
}
delay(1);
SCLK_1;
_NOP();
// _NOP();
receivedata=receivedata<<1;
temp1=P3IN;
if((temp1 & 0x04)==0x04)
{
receivedata |=1;
}
delay(1);
temp=temp<<1;
}
comm_data0[j]=receivedata;
for(i=0;i<8;i++)
{
SCLK_0;
delay(1);
SCLK_1;
_NOP();
//_NOP();
receivedata=receivedata<<1;
temp1=P3IN;
if((temp1 & 0x04)==0x04) ///( DIN_IN )
{
receivedata |=1;
}
delay(1);
}
comm_data0[1]=receivedata;
CS_1;
delay(4000);
delay(4000);
}
}
/////end///////
///---------------------------------main
int main( void )
{
unsigned char n;
WDTCTL=WDTPW+WDTHOLD;
BCSCTL1 &=~(XTS+XT2OFF); // 启动XT2晶振8M,ACLK为XT1低频32768
do
{
IFG1 &=~OFIFG; //清OSCFault标志
for(n=0xFF;n>0;n--); //延时等待
}
while((IFG1 & OFIFG)!=0); //查OSCFault,为0时转换完成
BCSCTL2 |=SELS; //SMCLK 为XT2 调试用
// BCSCTL2 &=~SELS; //SMCLK 为DCO
BCSCTL2 |= SELM1; // MCLK = XT2 8M
BCSCTL2 |=DIVM_0; //分频系数为1
init_ioport();
init_timerA();
init_timerB();
// init_ADC();
init_UART1();
init_UART0();
IE2|=URXIE1;
IE1|=URXIE0;
_EINT(); //允许中断
_NOP();
// write16350();
//0;
while(1)
{
//channel=0x02; //// select channel, 0 is A0,1 is A1 ,2 is A0 and A1
//ADC12IE=0X002; /// enable adc interrupt
//ADC12CTL0 |=ENC; ////enable adc
//ADC12CTL0 |= ADC12SC; ///start adc
WDTCTL=WDTPW+WDTHOLD; ////关闭看门狗定时器
/////-------------------------celiang ad0
while (1)
{
comm_data1[0]=0x38;
comm_data1[1]=0x00;
read16350();
_NOP();
// SCLK_1;
// delay(1);
// SCLK_0;
// delay(1);
//while(1);
}
}
}
////////============================/////中断
////232接收中断//// USART1
#pragma vector=USART1RX_VECTOR
__interrupt void UART1RX (void)
{unsigned char rcv_len,temp=1;////BCC_sum=0,index,,temp;
_EINT();
IE2 &=~URXIE1;
_NOP();
comm_data1[0]=RXBUF1;
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 |=CCIE; //中断位为1,表示中断允许
CCR0=8000; // 定时1毫秒
TAR=0;
TACTL = TASSEL_2 + MC_1; //选择子系统时钟SMCLK(SMCLK选 MCLK),增计数模式,计数器计数到CCR0,再清零计数
/// comm_data[0]=0xff; //rcv_len-1原来是变量,为了将来可能改数量 借用0元素,存放计算接收数据的校验和
for(rcv_len=1;rcv_len<3;rcv_len++)
{ _NOP();
while(1)
{
if(IFG2 & URXIFG1) // 如果接收到数据if((IFG2 & URXIFG1)==1)
{
comm_data1[rcv_len]=RXBUF1; //接收数据存在临时变量temp
semiseconde=0; //定时计时变量清零
TAR=0X0000; //16位计数器内容,执行计数单元
temp=1;
break; //跳出while循环
}
else
{
if(semiseconde>1000) //如果没接收到数据,而且超过1秒
{
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 &=~CCIE; //中断位为0,表示中断禁止
TAR=0X0000; //16位计数器内容,执行计数单元
CCR0=0; //定时数据清零 调试用
semiseconde=0;
P5OUT |=BIT0; //点亮通讯故障指示灯
temp=0;
break; //跳出while循环
}
}
}
if(temp==0)
{
IE2|=URXIE1;
break; //跳出for 循环
}
}
if(temp==1)
{
//status=0;//1;
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 &=~CCIE; //中断位为0,表示中断禁止
TAR=0X0000; //16位计数器内容,执行计数单元
CCR0=0; //定时数据清零 调试用
semiseconde=0;
while ((IFG2 & UTXIFG1) == 0); // USART0 TX buffer ready?
TXBUF1 = 0XFF; //通讯正确返回FF
P5OUT &=~BIT0; //熄灭通讯故障指示灯
IE2|=URXIE1;
}
//========IE2 |=URXIE1;
///P5OUT |=BIT0; //点亮通讯故障指示灯
}
///// end接收中断 /////
////SPI接收中断//// USART0
#pragma vector=USART0RX_VECTOR
__interrupt void UART0RX (void)
{ unsigned char rcv_len,temp=1;////BCC_sum=0,index,,temp;
_EINT();
IE1 &=~URXIE0;
_NOP();
comm_data0[0]=RXBUF0;
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 |=CCIE; //中断位为1,表示中断允许
CCR0=8000; // 定时1毫秒
TAR=0;
TACTL = TASSEL_2 + MC_1; //选择子系统时钟SMCLK(SMCLK选 MCLK),增计数模式,计数器计数到CCR0,再清零计数
for(rcv_len=1;rcv_len<2;rcv_len++)
{
while(1)
{
if(IFG1 & URXIFG0) // 如果接收到数据if((IFG2 & URXIFG1)==1)
{
comm_data1[rcv_len]=RXBUF0; //接收数据存在临时变量temp
semiseconde=0; //定时计时变量清零
TAR=0X0000; //16位计数器内容,执行计数单元
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 &=~CCIE; //中断位为0,表示中断禁止
TAR=0X0000; //16位计数器内容,执行计数单元
CCR0=0; //定时数据清零 调试用
semiseconde=0;
P5OUT &=~BIT0; //熄灭通讯故障指示灯
temp=1;
break; //跳出while循环
}
else
{
if(semiseconde>1000) //如果没接收到数据,而且超过1秒
{
TACTL=MC_0; //停止模式,用于定时器暂停
CCTL0 &=~CCIE; //中断位为0,表示中断禁止
TAR=0X0000; //16位计数器内容,执行计数单元
CCR0=0; //定时数据清零 调试用
semiseconde=0;
P5OUT |=BIT1; //点亮通讯故障指示灯
temp=0;
break; //跳出while循环
}
}
}
if(temp==1)
{
//status=2;
}
if(temp==0)
{
// status=0;
break; //跳出for 循环
}
}
IE1|=URXIE0;
//P3OUT |=BIT0;
}
///// end接收中断 /////
#pragma vector=TIMERA0_VECTOR ////Ta 的中断程序
__interrupt void TimerA0 (void)
{
semiseconde=semiseconde+1; ///Ta的计时变量加1,过1毫秒就加一
} |
|