【电赛MSP430系列】GPIO、LED、按键、时钟、中断、串口、定时器、PWM、ADC

文章目录

  • MSP430
  • 一、GPIO
  • 二、点亮LED
  • 三、按键控制LED
  • 四、更改主时钟
  • 五、串口通信
  • 六、串口中断
  • 七、外部中断
  • 八、定时器
  • 九、定时器中断
  • 十、PWM
  • 十一、ADC


MSP430

MSP430 是德州仪器(TI)一款性能卓越的超低功耗 16 位单片机,自问世以来,MSP430 单片机一直是业内公认的功耗最低的单片机。除采用先进的制造工艺使芯片的静态电流尽可能降低外,MSP430 的独立可配置的时钟系统是其低功耗的基石之一。在追求绿色能源的今天,MSP430 超低功耗微控制器正以其超低功耗的特性,以及丰富多样化的外设受到越来越多设计者们的青睐。
在这里插入图片描述

一、GPIO

在这里插入图片描述
在这里插入图片描述

MSP430G2553共有两个通用数字端口P1和P2。

端口P1和 P2具有输入/输出\中断和外部模块功能,这些功能可以通过它们各自的7个控制寄存器的设置来实现。

  • 1. PxDIR输入/输出方向寄存器

相互独立的8位分别定义了8个引脚的输入/输出方向.8位在PUC后都被复位。使用时先根据需要定义端口的方向以满足设计者要求。
0 : I/O引脚被切换成输入模式;
1 : IO引脚被切换成输出模式。

  • 2. PxIN输入寄存器

输入寄存器是CPU扫描IO引脚信号的只读寄存器。通过读取该寄存器的内容获取IO端口的输入信号。此时引脚的方向必须选定为输入。读出时,该引脚的方向寄存器必须设置为输入模式。

  • 3. PxOUT输出寄存器

该寄存器为IO端口的输出缓冲寄存器。其内容可以像操作内存数据一样写入,以达到改变IO口状态的目的。在读取时输出缓存的内容与引脚方向定义无关。改变方向寄存器的内容,输出缓存的内容不受影响。

  • 4. PxIE中断使能寄存器

该寄存器的各引脚都有一位用以控制该引脚是否允许中断,该寄存器中0 :禁止该位中断;
1 :允许该位中断。

  • 5. PxIES 中断触发沿选择寄存器

如果允许Px口的某个引脚中断,还需定义该引脚的中断触发沿。该寄存器的8位分别定义了Px口的8个引脚的中断触发沿。
0:上升沿使相应标志置位;
1:下降沿使相应标志置位。

  • 6. PxIFG中断标志寄存器

该寄存器有8个标志位,它们含有相应引脚是否有待处理中断的信息,即
相应引脚是否有中断请求。如果Px的某个引脚允许中断,同时选择上升沿,则当该引脚发生由低电平向高电平跳变时,PxFG的相应位就会置位,表明在该引脚上有中断事件发生。
0 :没有中断请求;1 :有中断请求。

  • 7. PxSEL功能选择寄存器

Pl和P2两端口还有其他片内外设功能,考虑减少引脚,将这些功能与芯片外的联系通过复用P1和P2引脚的方式来实现.PxSEL用来选择引脚的IO端口功能与外围模块功能。
0 :选择引脚为I/O端口;
1 :选择引脚为外围模块功能。

以下我以msp430g2553为例,解析GPIO的使用。

二、点亮LED

在这里插入图片描述
由上方电路图可读:

  • LED灯为P1.0和P1.6引脚,与下方GND相连,则为高电平驱动。
  • 按键为P1.3引脚,默认为悬空状态,当按键按下时与GND相连,为低电平状态。
#include <msp430.h> 

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// 关闭看门狗
	
	/*初始化LED2为输出*/
	P1DIR |= BIT6;

	/*初始化LED2为低电平,熄灭*/
	P1OUT &= ~BIT6;

	/*初始化KEY P1.3为输入*/
	P1DIR &= ~BIT3;
	/*使能P1.3口的上拉电阻*/
	P1REN |= BIT3;
	P1OUT |= BIT3;

	while(1)
	{
	    if(P1IN & BIT3) /*如果P1.3口为高电平,证明按键没有被按下*/
	    {
	        P1OUT &= ~BIT6; //熄灭LED2
	    }
	    else
	    {
	        P1OUT |= BIT6;  //点亮LED2
	    }
	}
	return 0;
}

三、按键控制LED

#include <msp430.h> 

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	
	/*初始化LED2为输出*/
	P1DIR |= BIT6;

	/*初始化LED2为低电平,熄灭*/
	P1OUT &= ~BIT6;

	/*初始化KEY P1.3为输入*/
	P1DIR &= ~BIT3;
	/*使能P1.3口的上拉电阻*/
	P1REN |= BIT3;
	P1OUT |= BIT3;

	while(1)
	{
	    if(P1IN & BIT3) /*如果P1.3口为高电平,证明按键没有被按下*/
	    {
	        P1OUT &= ~BIT6; //熄灭LED2
	    }
	    else
	    {
	        P1OUT |= BIT6;  //点亮LED2
	    }
	}
	return 0;
}

四、更改主时钟

#include <msp430.h> 

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    /*设置MCLK频率1,8,12,16*/
    DCOCTL = CALDCO_16MHZ;
    BCSCTL1 = CALBC1_16MHZ;

    /*初始化LED2所在的IO口P1.6设置为输出*/
    P1DIR |= BIT6;
    /*初始化LED2 为低电平*/
    P1OUT &= ~BIT6;

    while(1)
    {
        P1OUT ^= BIT6;
        __delay_cycles(500000);
    }
    return 0;
}

五、串口通信

在这里插入图片描述

#include <msp430.h> 
#include "stdint.h"
/*
 * @fn:    void InitSystemClock(void)
 * @brief: 初始化系统时钟
 * @para:  none
 * @return:none
 * @comment: 初始化系统时钟
 */
void InitSystemClock(void)
{
    /*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    /*配置SMCLK的时钟源为DCO*/
    BCSCTL2 &= ~SELS;
    /*SMCLK的分频系数置为1*/
    BCSCTL2 &= ~(DIVS0 | DIVS1);
}

/*
 * @fn:    void InitUART(void)
 * @brief: 初始化串口,包括设置波特率,数据位,校验位等
 * @para:  none
 * @return:none
 * @comment: 初始化串口
 */
void InitUART(void)
{
    /*复位USCI_Ax*/
    UCA0CTL1 |= UCSWRST;

    /*设置为异步模式*/
    UCA0CTL0 &= ~UCSYNC;

    /*配置UART时钟源为SMCLK*/
    UCA0CTL1 |= UCSSEL1;

    /*配置波特率为9600*/
    UCA0BR0 = 0x68;
    UCA0BR1 = 0x00;
    UCA0MCTL = 1 << 1;

    /*配置端口,使能端口复用*/
    P1SEL   |= BIT1 + BIT2;
    P1SEL2  |= BIT1 + BIT2;

    /*清除复位位,使能UART*/
    UCA0CTL1 &= ~UCSWRST;
}

/*
 * @fn:    void UARTSendString(uint8_t *pbuff, uint_8 num)
 * @brief: 初始化串口发送字符串
 * @para:  pbuff:指向要发送字符串的指针
 *         num:要发送的字符个数
 * @return:none
 * @comment: 初始化串口发送字符串
 */
void UARTSendString(uint8_t *pbuff, uint8_t num)
{
    uint8_t cnt = 0;
    for(cnt = 0; cnt < num; cnt++)
    {
        /*判断是否有数据正在发送*/
        while(UCA0STAT & UCBUSY);
        UCA0TXBUF = *(pbuff + cnt);
    }
}

/*
 * @fn:    void PrintNumber(uint16_t num)
 * @brief: 初始化串口发送数字
 * @para:  num:变量
 * @return:none
 * @comment: 初始化串口发送数字
 */
void PrintNumber(uint16_t num)
{
    uint8_t cnt = 0;
    uint8_t buff[6] = {0,0,0,0,0,'\n'};

    for(cnt = 0; cnt < 5; cnt++)
    {
        buff[4 - cnt] = (uint8_t)(num % 10 + '0');
        num /= 10;
    }
    UARTSendString(buff,6);
}


int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    InitSystemClock();
    InitUART();

    while(1)
    {
        PrintNumber(23456);
        __delay_cycles(500000);
    }

    return 0;
}

六、串口中断

#include <msp430.h> 
#include "stdint.h"

uint8_t combuff[20] = {0};  //长度为20的命令缓冲区,用于保存串口接收到的命令
uint8_t iscomend = 0;   //命令结束标志位
/*
 * @fn:    void InitSystemClock(void)
 * @brief: 初始化系统时钟
 * @para:  none
 * @return:none
 * @comment: 初始化系统时钟
 */
void InitSystemClock(void)
{
    /*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    /*配置SMCLK的时钟源为DCO*/
    BCSCTL2 &= ~SELS;
    /*SMCLK的分频系数置为1*/
    BCSCTL2 &= ~(DIVS0 | DIVS1);
}

/*
 * @fn:    void InitUART(void)
 * @brief: 初始化串口,包括设置波特率,数据位,校验位等
 * @para:  none
 * @return:none
 * @comment: 初始化串口
 */
void InitUART(void)
{
    /*复位USCI_Ax*/
    UCA0CTL1 |= UCSWRST;

    /*设置为异步模式*/
    UCA0CTL0 &= ~UCSYNC;

    /*配置UART时钟源为SMCLK*/
    UCA0CTL1 |= UCSSEL1;

    /*配置波特率为9600*/
    UCA0BR0 = 0x68;
    UCA0BR1 = 0x00;
    UCA0MCTL = 1 << 1;

    /*配置端口,使能端口复用*/
    P1SEL   |= BIT1 + BIT2;
    P1SEL2  |= BIT1 + BIT2;

    /*清除复位位,使能UART*/
    UCA0CTL1 &= ~UCSWRST;

    /*接收中断启用*/
    IE2 |= UCA0RXIE;
    /*清空接收中断标志*/
    IFG2 &= ~UCA0RXIFG;
}

/*
 * @fn:    void UARTSendString(uint8_t *pbuff, uint_8 num)
 * @brief: 初始化串口发送字符串
 * @para:  pbuff:指向要发送字符串的指针
 *         num:要发送的字符个数
 * @return:none
 * @comment: 初始化串口发送字符串
 */
void UARTSendString(uint8_t *pbuff, uint8_t num)
{
    uint8_t cnt = 0;
    for(cnt = 0; cnt < num; cnt++)
    {
        /*判断是否有数据正在发送*/
        while(UCA0STAT & UCBUSY);
        UCA0TXBUF = *(pbuff + cnt);
    }
}

/*
 * @fn:    void PrintNumber(uint16_t num)
 * @brief: 初始化串口发送数字
 * @para:  num:变量
 * @return:none
 * @comment: 初始化串口发送数字
 */
void PrintNumber(uint16_t num)
{
    uint8_t cnt = 0;
    uint8_t buff[6] = {0,0,0,0,0,'\n'};

    for(cnt = 0; cnt < 5; cnt++)
    {
        buff[4 - cnt] = (uint8_t)(num % 10 + '0');
        num /= 10;
    }
    UARTSendString(buff,6);
}

/*
 * @fn:    void Execute(uint8_t *combuff)
 * @brief: 串口命令执行函数
 * @para:  combuff:指向串口命令缓冲区的指针
 * @return:none
 * @comment: 串口命令执行函数
 */
void Execute(uint8_t *combuff)
{
    const uint8_t charbuff[5][10] = {"王龙","米雷龙","班长","LED1 ON!","LED1 OFF!"};
    if(combuff[0] == charbuff[0][0] && combuff[1] == charbuff[0][1])
    {
        UARTSendString("aa",2);
    }
    else if(combuff[0] == charbuff[1][0] && combuff[1] == charbuff[1][1])
    {
        UARTSendString("bb",2);
    }
    else if(combuff[0] == charbuff[2][0] && combuff[1] == charbuff[2][1])
    {
        UARTSendString("cc",2);
    }
    else if(combuff[0] == charbuff[3][0] && combuff[6] == charbuff[3][6])
    {
        UARTSendString("Yes,LED ON!",11);
        P1OUT |= BIT0;
    }
    if(combuff[0] == charbuff[4][0] && combuff[6] == charbuff[4][6])
    {
        UARTSendString("Yes,LED OFF!",12);
        P1OUT &= ~BIT0;
    }
}


int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    InitSystemClock();
    InitUART();
    P1DIR |= BIT0;
    P1OUT &= ~BIT0;
    __bis_SR_register(GIE);//打开总中断
    while(1)
    {
       if(iscomend)
       {
           iscomend = 0; //清除标志位,防止重复执行
           Execute(combuff);
       }
    }

    return 0;
}

#pragma vector = USCIAB0RX_VECTOR
__interrupt void UART_Receive_ISR(void)    //Port1_ISR(void)   中断服务函数
{
    static uint8_t cnt = 0;
    if(IFG2 & UCA0RXIFG)//检测是否是USCI_AO的接收中断,USCI_AO和USCI_BO的接收中断共享同一向量
    {

        IFG2 &= ~UCA0RXIFG; //清空接收中断标志
        combuff[cnt++] = UCA0RXBUF; //保存命令
        cnt %= 20;  //防止cnt大于20,导致缓存区溢出
        if(combuff[cnt - 1] == '\n')
        {
            cnt = 0;    //复位计数器
            iscomend = 1;   //命令接收完毕标志
        }
    }
    /*清空接收中断标志*/
    IFG2 &= ~UCA0RXIFG;
}

七、外部中断

#include <msp430.h> 


/**
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    /*初始化LED2为输出*/
    P1DIR |= BIT6;

    /*初始化LED2为低电平,熄灭*/
    P1OUT &= ~BIT6;

    /*初始化KEY P1.3为输入*/
    P1DIR &= ~BIT3;
    /*使能P1.3口的上拉电阻*/
    P1REN |= BIT3;
    P1OUT |= BIT3;

    /*打开P1.3口的中断*/
    P1IE |= BIT3;
    /*设定为下降沿触发*/
    P1IES |= BIT3;
    /*清除中断标志位*/
    P1IFG &= ~BIT3;
    /*打开全局中断*/
    __bis_SR_register(GIE);

    while(1)
    {
    }
    return 0;
}

#pragma vector = PORT1_VECTOR
__interrupt void Port1_ISR(void)    //Port1_ISR(void)   中断服务函数
{
    if(P1IFG & BIT3)   //判断是否P1.3产生中断
    {
        P1OUT ^= BIT6;
        P1IFG  &= ~ BIT3;   //清除标志位
    }
}

八、定时器

在这里插入图片描述

#include <msp430.h> 
#include "stdint.h"

int main(void)
{
    uint8_t cnt = 0;
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	/*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

   P1DIR |= BIT0 ;

   /*配置时钟源为SMCLK*/
   TA1CTL |= TASSEL_2;
   /*设置工作模式为Up Mode*/
   TA1CTL |= MC_1;
   /*设置定时时间间隔*/
   TA1CCR0 = 49999;     //0.05s
	while(1)
	{
	    if(TA1CTL & TAIFG)
	    {
	        cnt++;
	        TA1CTL &= ~TAIFG;   //清除标志位
	        if(cnt == 20)
	        {
	            P1OUT ^= BIT0;
	            cnt = 0;
	        }
	    }
	}

	return 0;
}

九、定时器中断

#include <msp430.h> 
#include "stdint.h"

uint32_t currenttime = 40500;   //用来保存时间的变量,初值代表11:15:00
uint8_t flag = 0;
/*
 * @fn:    void InitSystemClock(void)
 * @brief: 初始化系统时钟
 * @para:  none
 * @return:none
 * @comment: 初始化系统时钟
 */
void InitSystemClock(void)
{
    /*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    /*配置SMCLK的时钟源为DCO*/
    BCSCTL2 &= ~SELS;
    /*SMCLK的分频系数置为1*/
    BCSCTL2 &= ~(DIVS0 | DIVS1);
}

/*
 * @fn:    void InitUART(void)
 * @brief: 初始化串口,包括设置波特率,数据位,校验位等
 * @para:  none
 * @return:none
 * @comment: 初始化串口
 */
void InitUART(void)
{
    /*复位USCI_Ax*/
    UCA0CTL1 |= UCSWRST;

    /*设置为异步模式*/
    UCA0CTL0 &= ~UCSYNC;

    /*配置UART时钟源为SMCLK*/
    UCA0CTL1 |= UCSSEL1;

    /*配置波特率为9600*/
    UCA0BR0 = 0x68;
    UCA0BR1 = 0x00;
    UCA0MCTL = 1 << 1;

    /*配置端口,使能端口复用*/
    P1SEL   |= BIT1 + BIT2;
    P1SEL2  |= BIT1 + BIT2;

    /*清除复位位,使能UART*/
    UCA0CTL1 &= ~UCSWRST;

    /*接收中断启用*/
    IE2 |= UCA0RXIE;
    /*清空接收中断标志*/
    IFG2 &= ~UCA0RXIFG;
}

/*
 * @fn:    void UARTSendString(uint8_t *pbuff, uint_8 num)
 * @brief: 初始化串口发送字符串
 * @para:  pbuff:指向要发送字符串的指针
 *         num:要发送的字符个数
 * @return:none
 * @comment: 初始化串口发送字符串
 */
void UARTSendString(uint8_t *pbuff, uint8_t num)
{
    uint8_t cnt = 0;
    for(cnt = 0; cnt < num; cnt++)
    {
        /*判断是否有数据正在发送*/
        while(UCA0STAT & UCBUSY);
        UCA0TXBUF = *(pbuff + cnt);
    }
}

/*
 * @fn:    void PrintTime(uint32_t time)
 * @brief: 初始化串口发送字符串
 * @para:  pbuff:指向要发送字符串的指针
 *         num:要发送的字符个数
 * @return:none
 * @comment: 初始化串口发送字符串
 */
void PrintTime(uint32_t time)
{
    uint8_t charbuff[] = {0,0,':',0,0,':',0,0,'\n'};
    charbuff[7] = (uint8_t)((time % 60) % 10) + '0';    //得到当前秒个位
    charbuff[6] = (uint8_t)((time % 60) / 10) + '0';    //得到当前秒十位
    charbuff[4] = (uint8_t)((time % 3600) / 60 % 10) + '0';    //得到当前分个位
    charbuff[3] = (uint8_t)((time % 3600) / 60 / 10) + '0';    //得到当前分十位
    charbuff[1] = (uint8_t)((time / 3600) % 10) + '0';    //得到当前时个位
    charbuff[0] = (uint8_t)(time / 3600 / 10) + '0';    //得到当前时十位
    UARTSendString("当前时间:",10);
    UARTSendString(charbuff,9);
}

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    /*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    InitSystemClock();
    InitUART();

    P1DIR |= BIT0 ;

    /*配置时钟源为SMCLK*/
    TA1CTL |= TASSEL_2;
    /*设置工作模式为Up Mode*/
    TA1CTL |= MC_1;
    /*设置定时时间间隔*/
    TA1CCR0 = 49999;     //0.05s

    /*打开定时器TAIFG中断*/
    TA1CTL |= TAIE;
    /*打开全局中断*/
    __bis_SR_register(GIE);

    while(1)
    {
        if(flag == 1)
        {
            flag = 0;
            P1OUT ^= BIT0;
            PrintTime(currenttime);
        }
    }

    return 0;
}

#pragma vector = TIMER1_A1_VECTOR
__interrupt void Timer_Tick(void)
{
    static uint8_t cnt = 0;
    switch(TA1IV) //读取的话无需手动清零标志位
    {
    case 0x02:
        break;
    case 0x04:
        break;
    case 0x0A:
        cnt++;
        if(cnt == 20)
        {
            cnt = 0;
            flag = 1;   //1s时间到了
            currenttime ++; //时间加1
            currenttime %= 86400;   //一天24小时,防止溢出
        }
        break;
    default:
        break;
    }
}

十、PWM

#include <msp430.h> 

int main(void)
{
    unsigned int cnt = 0;
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	
	/*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    /*初始化P1.6为输入*/
    P1DIR &= ~BIT6;

    /*设置时钟源为SMCLK*/
    TA1CTL |= TASSEL_2;
    /*设置工作模式为Up & Dowm*/
    TA1CTL |= MC_0 | MC_1;
    /*设置TA1CCR0为0x00ff*/
    TA1CCR0 = 0x00FF;
    /*设置TA1CCR2为0x00ff*/
    TA1CCR2 = 0x00FF;   //占空比 = (TACCR0 - TACCR2)/ TACCR0 频率 = SMCLK / (TACCR0+1)/2

    /*设置为比较模式*/
    TA1CCTL0 &= ~CAP;
    TA1CCTL2 &= ~CAP;
    /*设置比较输出模式*/
    TA1CCTL2 |= OUTMOD_6;
    /*设置IO复用*/
    P2SEL |= BIT5;
    P2DIR |= BIT5;

    while(1)
    {
        for(cnt = 0;cnt < 0x00FF; cnt++)
        {
           TA1CCR2 =  cnt;
           __delay_cycles(5000);
        }

        for(cnt = 0x00FF;cnt > 0; cnt--)
        {
           TA1CCR2 =  cnt;
           __delay_cycles(5000);
        }
    }

	return 0;
}

十一、ADC

在这里插入图片描述

#include <msp430.h> 
#include "stdint.h"

/*
 * @fn:    void InitSystemClock(void)
 * @brief: 初始化系统时钟
 * @para:  none
 * @return:none
 * @comment: 初始化系统时钟
 */
void InitSystemClock(void)
{
    /*配置DCO为1MHZ时钟*/
    DCOCTL = CALDCO_1MHZ;
    BCSCTL1 = CALBC1_1MHZ;

    /*配置SMCLK的时钟源为DCO*/
    BCSCTL2 &= ~SELS;
    /*SMCLK的分频系数置为1*/
    BCSCTL2 &= ~(DIVS0 | DIVS1);
}

/*
 * @fn:    void InitUART(void)
 * @brief: 初始化串口,包括设置波特率,数据位,校验位等
 * @para:  none
 * @return:none
 * @comment: 初始化串口
 */
void InitUART(void)
{
    /*复位USCI_Ax*/
    UCA0CTL1 |= UCSWRST;

    /*设置为异步模式*/
    UCA0CTL0 &= ~UCSYNC;

    /*配置UART时钟源为SMCLK*/
    UCA0CTL1 |= UCSSEL1;

    /*配置波特率为9600*/
    UCA0BR0 = 0x68;
    UCA0BR1 = 0x00;
    UCA0MCTL = 1 << 1;

    /*配置端口,使能端口复用*/
    P1SEL   |= BIT1 + BIT2;
    P1SEL2  |= BIT1 + BIT2;

    /*清除复位位,使能UART*/
    UCA0CTL1 &= ~UCSWRST;

    /*接收中断启用*/
    IE2 |= UCA0RXIE;
    /*清空接收中断标志*/
    IFG2 &= ~UCA0RXIFG;
}

/*
 * @fn:    void UARTSendString(uint8_t *pbuff, uint_8 num)
 * @brief: 初始化串口发送字符串
 * @para:  pbuff:指向要发送字符串的指针
 *         num:要发送的字符个数
 * @return:none
 * @comment: 初始化串口发送字符串
 */
void UARTSendString(uint8_t *pbuff, uint8_t num)
{
    uint8_t cnt = 0;
    for(cnt = 0; cnt < num; cnt++)
    {
        /*判断是否有数据正在发送*/
        while(UCA0STAT & UCBUSY);
        UCA0TXBUF = *(pbuff + cnt);
    }
}

/*
 * @fn:    void PrintNumber(uint16_t num)
 * @brief: 初始化串口发送数字
 * @para:  num:变量
 * @return:none
 * @comment: 初始化串口发送数字
 */
void PrintNumber(uint16_t num)
{
    uint8_t cnt = 0;
    uint8_t buff[6] = {0,0,0,0,0,'\n'};

    for(cnt = 0; cnt < 5; cnt++)
    {
        buff[4 - cnt] = (uint8_t)(num % 10 + '0');
        num /= 10;
    }
    UARTSendString(buff,6);
}

/*
 * @fn:    void PrintFloat(float num)
 * @brief: 初始化串口发送浮点型数字
 * @para:  num:浮点型变量
 * @return:none
 * @comment: 初始化串口发送浮点型数字
 */
void PrintFloat(float num)
{
    uint8_t buff[] = {0,'.',0,0,0,'\n'};
    uint16_t temp = (uint16_t)(num * 1000);
    buff[0] = (uint8_t)(temp / 1000) + '0';
    buff[2] = (uint8_t)((temp % 1000) / 100) + '0';
    buff[3] = (uint8_t)((temp / 100) / 10) + '0';
    buff[4] = (uint8_t)(temp % 10) + '0';
    UARTSendString(buff,6);
}

/*
 * @fn:    void InitADC(void)
 * @brief: ADC初始化
 * @para:  none
 * @return:none
 * @comment: ADC初始化
 */
void InitADC(void)
{
    /*设置ADC时钟MCLK*/
    ADC10CTL1 |= ADC10SSEL_2;
    /*ADC 2分频*/
    ADC10CTL1 |= ADC10DIV_0;
    /*设置ADC基准源*/
    ADC10CTL0 |= SREF_1;
    /*设置ADC采样保持时间64CLK*/
    ADC10CTL0 |= ADC10SHT_3;
    /*设置ADC采样率200k*/
    ADC10CTL0 &= ~ADC10SR;
    /*ADC基准选择2.5V*/           /* ADC基准选择1.5V */
    ADC10CTL0 |= REF2_5V;         /* ADC10CTL0 &= ~REF2_5V; */
    /*开启基准*/
    ADC10CTL0 |= REFON;
    /*选择ADC输入通道A0*/
    ADC10CTL1 |= INCH_0;
    /*允许A0模拟输入*/
    ADC10AE0 |= 0x0001;
    /*开启ADC*/
    ADC10CTL0 |= ADC10ON;
}

/*
 * @fn:    uint16_t GetADCValue(void)
 * @brief: 进行一次ADC转换并返回ADC转换结果
 * @para:  none
 * @return:ADC转换结果
 * @comment: ADC转换结果为10bit,以uint16_t类型返回,低10位有效数据
 */
uint16_t GetADCValue(void)
{
    /*开始转换*/
    ADC10CTL0 |= ADC10SC|ENC;
    /*等待转换完成*/
    while(ADC10CTL1 & ADC10BUSY);
    /*返回结果*/
    return ADC10MEM;
}

int main(void)
{
    float voltage = 0.0;
    uint16_t adcvalue = 0;
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	InitSystemClock();
	InitUART();
	InitADC();
	
	while(1)
	{
	    adcvalue = GetADCValue();
	    voltage = adcvalue * 2.5 / 1023;

	    UARTSendString("ADC10转接结果为:",17);
	    PrintNumber(adcvalue);
	    UARTSendString("相应电压值为:",14);
	    PrintFloat(voltage);
        __delay_cycles(300000);
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/330.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

程序员的逆向思维

前要&#xff1a; 为什么你读不懂面试官提问的真实意图&#xff0c;导致很难把问题回答到面试官心坎上? 为什么在面试结束时&#xff0c;你只知道问薪资待遇&#xff0c;不知道如何高质量反问? 作为一名程序员&#xff0c;思维和技能是我们职场生涯中最重要的两个方面。有时候…

【微信小程序】-- 网络数据请求(十九)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

到底什么是跨域,如何解决跨域(常见的几种跨域解决方案)?

文章目录1、什么是跨域2、解决跨域的几种方案2.1、JSONP 方式解决跨域2.2、CORS 方式解决跨域&#xff08;常见&#xff0c;通常仅需服务端修改即可&#xff09;2.3、Nginx 反向代理解决跨域&#xff08;推荐使用&#xff0c;配置简单&#xff09;2.4、WebSocket 解决跨域2.5、…

软测面试了一个00后,绝对能称为是内卷届的天花板

前言 公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资也不低&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。令我印象最深的是一个00后测试员&#xf…

【JavaScript 逆向】百度旋转验证码逆向分析

声明本文章中所有内容仅供学习交流&#xff0c;相关链接做了脱敏处理&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01;案例目标爱企查百度安全验证百度搜索&#xff1a;aHR0cHM6Ly93YXBwYXNzLmJhaWR1LmNvbS9zdGF0aWMvY2FwdGNoYS8以上均做了脱敏处理&#xff0c;B…

操作系统(2.2)--进程的描述与控制

目录 二、进程的描述 1.进程的定义和特征 1.1进程的定义 1.2进程的特征 2.进程的基本状态及转换 2.1进程的三种基本状态 2.2 三种基本状态的转换 2.3创建状态和中止状态 3.挂起操作和进程状态的转换 3.1 挂起状态的引入 3.2 引入挂起操作后三个进程状态的转换 …

07从零开始学Java之如何正确的编写Java代码?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者前言在上一篇文章中&#xff0c;壹哥带领大家开始编写了第一个Java案例&#xff0c;在我们的cmd命令窗口中输出了”Hello World“这…

【蓝桥杯-筑基篇】常用API 运用(1)

&#x1f353;系列专栏:蓝桥杯 &#x1f349;个人主页:个人主页 目录 &#x1f34d;1.输入身份证&#xff0c;判断性别&#x1f34d; &#x1f34d;2.输入英语句子&#xff0c;统计单词个数&#x1f34d; &#x1f95d;3.加密解密&#x1f95d; &#x1f30e;4.相邻重复子串…

【6G 新技术】6G数据面介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

订单30分钟未支付自动取消怎么实现?

目录了解需求方案 1&#xff1a;数据库轮询方案 2&#xff1a;JDK 的延迟队列方案 3&#xff1a;时间轮算法方案 4&#xff1a;redis 缓存方案 5&#xff1a;使用消息队列了解需求在开发中&#xff0c;往往会遇到一些关于延时任务的需求。例如生成订单 30 分钟未支付&#xff0…

HashMap的实际开发使用

目 录 前言 一、HashMap是什么&#xff1f; 二、使用步骤 1.解析一下它实现的原理 ​编辑 2.实际开发使用 总结 前言 本章&#xff0c;只是大概记录一下hashMap的简单使用方法&#xff0c;以及理清一下hashMap的put方法的原理&#xff0c;以及get方法的原理。 一、Has…

如何使用 Python 检测和识别车牌(附 Python 代码)

文章目录创建Python环境如何在您的计算机上安装Tesseract OCR&#xff1f;技术提升磨砺您的Python技能车牌检测与识别技术用途广泛&#xff0c;可以用于道路系统、无票停车场、车辆门禁等。这项技术结合了计算机视觉和人工智能。 本文将使用Python创建一个车牌检测和识别程序。…

【Linux】目录和文件的权限

Linux中的权限有什么作用Linux权限管理文件访问者的分类文件类型和访问权限&#xff08;事物属性&#xff09;**文件权限值的表示方法**文件访问权限的相关设置方法chmodchownchgrpumaskumask使用 sudo分配权限目录的权限Linux中的权限有什么作用 Linux下有两种用户&#xff1…

【C缺陷与陷阱】----语义“陷阱”

&#x1f4af;&#x1f4af;&#x1f4af; 本篇处理的是有关语义误解的问题&#xff1a;即程序员的本意是希望表示某种事物&#xff0c;而实际表示的却是另外一种事物。在本篇我们假定程序员对词法细节和语法细节的理解没有问题&#xff0c;因此着重讨论语义细节。导言&#xf…

SignalR+WebRTC技术实现音视频即时通讯功能

一、建立信令服务器 1、后台项目中新建一个对应的集线器类&#xff0c;取名VideoHub&#xff0c;并继承Hub类&#xff0c;Hub是SignalR的一个组件&#xff0c;它使用RPC接收从客户端发送来的消息&#xff0c;也能把消息发送给客户端。 2、VideoHub中定义一个静态的Concurrent…

java-正装照换底色小demo-技术分享

文章目录前言java-正装照换底色小demo-技术分享01 实现思路02 效果02::01 原图:02::02 执行单元测试:02::03 效果:03 编码实现前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞…

js逆向爬取某音乐网站某歌手的歌曲

js逆向爬取某音乐网站某歌手的歌曲一、分析网站1、案例介绍2、寻找列表页Ajax入口&#xff08;1&#xff09;页面展示图。&#xff08;2&#xff09;寻找部分歌曲信息Ajax的token。&#xff08;3&#xff09;寻找歌曲链接&#xff08;4&#xff09;获取歌曲名称和id信息3、寻找…

XXE漏洞复现

目录XML基础概念XML数据格式DTD基础定义DTD作用分类DTD实体实体的分类DTD元素XXE漏洞介绍实操如何探测xxe漏洞XML基础 概念 什么是XML 是一种可扩展标记语言 (Extensible Markup Language, XML) &#xff0c;标准通用标记语言的子集&#xff0c;可以用来标记数据、定义数据类型…

30个题型+代码(冲刺2023蓝桥杯)(中)

2023.3.13~4.13持续更新 目录 &#x1f34e;注意 &#x1f33c;前言 &#x1f33c;十&#xff0c;KMP&#xff08;留坑&#xff09; &#x1f33c;十一&#xff0c;Trie&#xff08;留坑&#xff09; &#x1f33c;十二&#xff0c;BFS &#x1f44a;(一)1562. 微博转发…

OpenAI 发布GPT-4——全网抢先体验

OpenAI 发布GPT-4 最近 OpenAI 犹如开挂一般&#xff0c;上周才刚刚推出GPT-3.5-Turbo API&#xff0c;今天凌晨再次祭出GPT-4这个目前最先进的多模态预训练大模型。与上一代GPT3.5相比&#xff0c;GPT-4最大的飞跃是增加了识图能力&#xff0c;并且回答准确性也得到显著提高。…