/*主函数 */
#include "msp430f5529.h"
#include "in430.h"
#include "HAL_PMM.h"
/*设置DAC0832和单片机各个管脚之间的关系*/
#define ILE P1OUT |=BIT2
#define CSN P1OUT &=~BIT3
#define WR1N P1OUT &=~BIT4
#define WR2N P1OUT &=~BIT5
#define XFERN P1OUT &=~BIT6
//-------------------------------------
#define ILEN P1OUT &=~BIT2
#define CS P1OUT |=BIT3
#define WR1 P1OUT |=BIT4
#define WR2 P1OUT |=BIT5
#define XFER P1OUT |=BIT6
/*定时器的周期个数*/
char half=50;
char all=100;//输出信号的频率是50000/all Hz 此处初值为500
unsigned int key; //key用来记录哪个键被按下
char func_num1=1;//func_num用来记录功能号(前3个功能)
char func_num2=0;//func_num用来记录功能号(后3个功能)
/*功能1:输出方波功能2:输出三角波功能3:输出正弦波
* 功能1:频率增加功能2:频率减小功能3:占空比变化
* 功能0:频率不变*/
char k=0; //从0开始,记录输出的点的序号
char i=0;//占空比增减
char j=0;//频率的增减
char sin[200]={
127,131,135,139,143,147,151,155,159,162,166,170,174,177,181,185,188
,192,195,198,202,205,208,211,214,217,220,222,225,227,230,232,234,236
,238,240,242,244,245,246,248,249,250,251,252,252,253,253,254,254,254
,254,254,253,253,252,252,251,250,249,248,246,245,244,242,240,238,236
,234,232,230,227,225,222,220,217,214,211,208,205,202,198,195,192,188
,185,181,177,174,170,166,162,159,155,151,147,143,139,135,131,127,123
,119,115,111,107,103,99,95,92,88, 84, 80, 77, 73, 69, 66, 62, 59
, 56, 52, 49, 46, 43, 40, 37, 34, 32, 29, 27, 24, 22, 20, 18, 16
, 14 , 12, 10, 9, 8, 6, 5, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0
, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 16, 18, 20, 22
, 24, 27, 29, 32, 34, 37, 40, 43, 46, 49, 52, 56, 59, 62, 66, 69, 73
, 77, 80, 84, 88, 92, 95, 99,103,107,111,115,119,123};
/*************************时延部分声明*************************/
#define CPU_CLOCK ((double)25000000)//主时钟频率为25M,最小延时就是125ns ???????????可以不一致吗?
#define delay_us(x) __delay_cycles((long)(CPU_CLOCK*(double)x/1000000))//调用编译器内部时延函数,延时x us=x*25*[1/(25M)] (25M是主时钟的频率<设定好主时钟频率后,就设好它了>)
//__delay_cycles((long)x),即代表延时x us
#define delay_ms(x) __delay_cycles((long)(CPU_CLOCK*(double)x/1000))//时延x ms =x*8000*1/8 us
/*************************初始化时钟*************************/
void initial_clock(void)
{
P5SEL |= BIT4|BIT5;
UCSCTL6 |= XCAP_3;
UCSCTL6 &= ~XT1OFF;//打开XT1,否则XT1LFOFFG可能报错
SetVCore(3); //提高Vcore电压到最高级,以满足倍频需求该函数位于HAL_PMM.H中
__bis_SR_register(SCG0);//该语法为固定格式,意为将括号内的变量置位,SCG0与系统工作模式有关,此时MCLK暂停工作
UCSCTL0 = 0; //先清零,FLL运行时,该寄存器系统会自动配置,不用管
UCSCTL1 = DCORSEL_6;
UCSCTL2 = FLLD_1 | 380;//FLLD=1,FLLN=380,则频率为2*(380+1)*32.768=24.969MHZ
__bic_SR_register(SCG0);
__delay_cycles(782000);//系统自带的精确延时,单位us
while (SFRIFG1 & OFIFG) {
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}
UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_3|SELM_3;
}
void initial_io(void)
{
/*P4口----输出,连接LCD12864,*/
P4DIR |=BIT0+BIT1+BIT2;
/*P3口----输出8位数据*/
P3DIR=0xff;//将P3所有口设为输出;不需要接入内部电阻
/*P1口----输出,连接DAC0832,向其写入数据*/
P1DIR |=BIT3+BIT4+BIT5+BIT6+BIT7;
/*P2口---连接按键,产生中断*/
//P2IFG =0x00; //消除中断标志
P2DIR &=~(BIT1);//P2口设为输入口,可以省略
P2REN |=BIT1; //用于按键接地型,使输入低电平和高电平都稳定 ??????????<-P209 不使用内部电阻,低电平时输出就不稳定吗?
P2OUT |=BIT1; //上拉????
P2IE |=BIT1; //允许中断
P2IES |=BIT1; //中断下降沿触发
__enable_interrupt();//开启总中断???为什么要在这里??
}
/*********************IO P管脚的 中断函数主体**********************/
/*********************判断按下了那个键盘,以及键盘按下的时间长短。**********************/
#pragma vector=PORT2_VECTOR
__interrupt void judge_io(void) //interrupt前面必须有__吗????????????
{
//key=P2IFG; //判断是哪个键被按下
key=2;
delay_ms(10); //延时10ms消除按下时抖动产生的影响
if(P1IN&key) //按下为低电平,不按仍为高电平
switch(key) //若按键短暂被按下,对采样频率和方波的占空比进行设置
{
case BIT1:func_num1=1;
case BIT3:func_num1=2;
case BIT4:func_num1=3;
case BIT5:func_num2=1;
case BIT6:func_num2=2;
case BIT7:func_num2=3;
case BIT0:func_num2=4;
}
P2IFG=0; //中断清零
//_EINT(); //打开中断,关闭中断是默认的
}
/*********************DAC0832的写入**********************/
void dac0832_write(char out)
{
ILE;
CSN;
WR2N;
__delay_cycles(4); //时延4个时钟周期,等信号稳定
WR1N;
P3OUT=out;
delay_us(1); //延时1us,传数据
WR1;
WR2;
CS;
}
/*********************TimerA的 中断函数初始化设置**********************/
/*********************设置时钟源,计数模式,打开中断**********************/
void initial_timer(void)
{
TA0CTL |=TASSEL_2+MC_1+TACLR+TAIE; //TA时钟源选择SMCLK(25MHz),连续增计数模式,增至TACCR0后,置0,并且清零,中断允许->要选25MHz吗??????
TA0CCR0=499; //定时器记到499时停止//50000Hz
TA0CCTL0 |=CCIE; //中断使能TA0???<-这里的0代表的都是中断源是TIMERA0里的0吗,不是
_EINT(); //开总中断
}
/*********************TimerA的 中断函数**********************/
/*********************实现func_num对应的相应功能**********************/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void) //CCIFG中断被响应后,该标志位自动清零
{
if(func_num1==1) //方波产生
{
if(k<(half+5*i+5*j))//i用来控制方波占空比,j用来控制频率的增减
{
dac0832_write((char)255);
k++;
}
else if(k<(all+10*j))
{
dac0832_write((char)0);
k++;
}
else
k=0;
}
if(func_num1==2) //三角波产生
{
if(k<(half+5*j))
{
dac0832_write((char)k);
k++;
}
else if(k<(all+10*j))
{
dac0832_write((char)(all-k));
k++;
}
else
k=0;
}
if(func_num1==3) //正弦波产生
{
if(k<(all+10*j))
{
dac0832_write(sin[k]);
k++;
}
else
k=0;
}
if(func_num2==1) //频率增加
{
if((all+10*j)>=0) //频率不为0,则可以继续减少
j--;
func_num2=0;//频率(或占空)比变化一次,频率(或占空)就比不再变化
}
if(func_num2==2) //频率减小
{
j++;
func_num2=0;
}
if(func_num2==3) //占空比增加-------------------少占空比减少
{
i++;
func_num2=0;
}
if(func_num2==4)
{
i--;
func_num2=0;
}
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;//关闭看门狗
initial_clock( ); //初始化时钟
initial_io();//初始化IO管脚
initial_timer( );//初始化定时器
while(1)
{
;
}
}
按键中断无法实现。按下按键P2.1后,在__interrupt void judge_io(void)中,无法将key设为2。望指教!
#include "msp430f5529.h"
#include "in430.h"
#include "HAL_PMM.h"
/*设置DAC0832和单片机各个管脚之间的关系*/
#define ILE P1OUT |=BIT2
#define CSN P1OUT &=~BIT3
#define WR1N P1OUT &=~BIT4
#define WR2N P1OUT &=~BIT5
#define XFERN P1OUT &=~BIT6
//-------------------------------------
#define ILEN P1OUT &=~BIT2
#define CS P1OUT |=BIT3
#define WR1 P1OUT |=BIT4
#define WR2 P1OUT |=BIT5
#define XFER P1OUT |=BIT6
/*定时器的周期个数*/
char half=50;
char all=100;//输出信号的频率是50000/all Hz 此处初值为500
unsigned int key; //key用来记录哪个键被按下
char func_num1=1;//func_num用来记录功能号(前3个功能)
char func_num2=0;//func_num用来记录功能号(后3个功能)
/*功能1:输出方波功能2:输出三角波功能3:输出正弦波
* 功能1:频率增加功能2:频率减小功能3:占空比变化
* 功能0:频率不变*/
char k=0; //从0开始,记录输出的点的序号
char i=0;//占空比增减
char j=0;//频率的增减
char sin[200]={
127,131,135,139,143,147,151,155,159,162,166,170,174,177,181,185,188
,192,195,198,202,205,208,211,214,217,220,222,225,227,230,232,234,236
,238,240,242,244,245,246,248,249,250,251,252,252,253,253,254,254,254
,254,254,253,253,252,252,251,250,249,248,246,245,244,242,240,238,236
,234,232,230,227,225,222,220,217,214,211,208,205,202,198,195,192,188
,185,181,177,174,170,166,162,159,155,151,147,143,139,135,131,127,123
,119,115,111,107,103,99,95,92,88, 84, 80, 77, 73, 69, 66, 62, 59
, 56, 52, 49, 46, 43, 40, 37, 34, 32, 29, 27, 24, 22, 20, 18, 16
, 14 , 12, 10, 9, 8, 6, 5, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0
, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 16, 18, 20, 22
, 24, 27, 29, 32, 34, 37, 40, 43, 46, 49, 52, 56, 59, 62, 66, 69, 73
, 77, 80, 84, 88, 92, 95, 99,103,107,111,115,119,123};
/*************************时延部分声明*************************/
#define CPU_CLOCK ((double)25000000)//主时钟频率为25M,最小延时就是125ns ???????????可以不一致吗?
#define delay_us(x) __delay_cycles((long)(CPU_CLOCK*(double)x/1000000))//调用编译器内部时延函数,延时x us=x*25*[1/(25M)] (25M是主时钟的频率<设定好主时钟频率后,就设好它了>)
//__delay_cycles((long)x),即代表延时x us
#define delay_ms(x) __delay_cycles((long)(CPU_CLOCK*(double)x/1000))//时延x ms =x*8000*1/8 us
/*************************初始化时钟*************************/
void initial_clock(void)
{
P5SEL |= BIT4|BIT5;
UCSCTL6 |= XCAP_3;
UCSCTL6 &= ~XT1OFF;//打开XT1,否则XT1LFOFFG可能报错
SetVCore(3); //提高Vcore电压到最高级,以满足倍频需求该函数位于HAL_PMM.H中
__bis_SR_register(SCG0);//该语法为固定格式,意为将括号内的变量置位,SCG0与系统工作模式有关,此时MCLK暂停工作
UCSCTL0 = 0; //先清零,FLL运行时,该寄存器系统会自动配置,不用管
UCSCTL1 = DCORSEL_6;
UCSCTL2 = FLLD_1 | 380;//FLLD=1,FLLN=380,则频率为2*(380+1)*32.768=24.969MHZ
__bic_SR_register(SCG0);
__delay_cycles(782000);//系统自带的精确延时,单位us
while (SFRIFG1 & OFIFG) {
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}
UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_3|SELM_3;
}
void initial_io(void)
{
/*P4口----输出,连接LCD12864,*/
P4DIR |=BIT0+BIT1+BIT2;
/*P3口----输出8位数据*/
P3DIR=0xff;//将P3所有口设为输出;不需要接入内部电阻
/*P1口----输出,连接DAC0832,向其写入数据*/
P1DIR |=BIT3+BIT4+BIT5+BIT6+BIT7;
/*P2口---连接按键,产生中断*/
//P2IFG =0x00; //消除中断标志
P2DIR &=~(BIT1);//P2口设为输入口,可以省略
P2REN |=BIT1; //用于按键接地型,使输入低电平和高电平都稳定 ??????????<-P209 不使用内部电阻,低电平时输出就不稳定吗?
P2OUT |=BIT1; //上拉????
P2IE |=BIT1; //允许中断
P2IES |=BIT1; //中断下降沿触发
__enable_interrupt();//开启总中断???为什么要在这里??
}
/*********************IO P管脚的 中断函数主体**********************/
/*********************判断按下了那个键盘,以及键盘按下的时间长短。**********************/
#pragma vector=PORT2_VECTOR
__interrupt void judge_io(void) //interrupt前面必须有__吗????????????
{
//key=P2IFG; //判断是哪个键被按下
key=2;
delay_ms(10); //延时10ms消除按下时抖动产生的影响
if(P1IN&key) //按下为低电平,不按仍为高电平
switch(key) //若按键短暂被按下,对采样频率和方波的占空比进行设置
{
case BIT1:func_num1=1;
case BIT3:func_num1=2;
case BIT4:func_num1=3;
case BIT5:func_num2=1;
case BIT6:func_num2=2;
case BIT7:func_num2=3;
case BIT0:func_num2=4;
}
P2IFG=0; //中断清零
//_EINT(); //打开中断,关闭中断是默认的
}
/*********************DAC0832的写入**********************/
void dac0832_write(char out)
{
ILE;
CSN;
WR2N;
__delay_cycles(4); //时延4个时钟周期,等信号稳定
WR1N;
P3OUT=out;
delay_us(1); //延时1us,传数据
WR1;
WR2;
CS;
}
/*********************TimerA的 中断函数初始化设置**********************/
/*********************设置时钟源,计数模式,打开中断**********************/
void initial_timer(void)
{
TA0CTL |=TASSEL_2+MC_1+TACLR+TAIE; //TA时钟源选择SMCLK(25MHz),连续增计数模式,增至TACCR0后,置0,并且清零,中断允许->要选25MHz吗??????
TA0CCR0=499; //定时器记到499时停止//50000Hz
TA0CCTL0 |=CCIE; //中断使能TA0???<-这里的0代表的都是中断源是TIMERA0里的0吗,不是
_EINT(); //开总中断
}
/*********************TimerA的 中断函数**********************/
/*********************实现func_num对应的相应功能**********************/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void) //CCIFG中断被响应后,该标志位自动清零
{
if(func_num1==1) //方波产生
{
if(k<(half+5*i+5*j))//i用来控制方波占空比,j用来控制频率的增减
{
dac0832_write((char)255);
k++;
}
else if(k<(all+10*j))
{
dac0832_write((char)0);
k++;
}
else
k=0;
}
if(func_num1==2) //三角波产生
{
if(k<(half+5*j))
{
dac0832_write((char)k);
k++;
}
else if(k<(all+10*j))
{
dac0832_write((char)(all-k));
k++;
}
else
k=0;
}
if(func_num1==3) //正弦波产生
{
if(k<(all+10*j))
{
dac0832_write(sin[k]);
k++;
}
else
k=0;
}
if(func_num2==1) //频率增加
{
if((all+10*j)>=0) //频率不为0,则可以继续减少
j--;
func_num2=0;//频率(或占空)比变化一次,频率(或占空)就比不再变化
}
if(func_num2==2) //频率减小
{
j++;
func_num2=0;
}
if(func_num2==3) //占空比增加-------------------少占空比减少
{
i++;
func_num2=0;
}
if(func_num2==4)
{
i--;
func_num2=0;
}
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;//关闭看门狗
initial_clock( ); //初始化时钟
initial_io();//初始化IO管脚
initial_timer( );//初始化定时器
while(1)
{
;
}
}
按键中断无法实现。按下按键P2.1后,在__interrupt void judge_io(void)中,无法将key设为2。望指教!