lab 9
熟悉串口工具
使用串口工具打开LaunchPad开发板XDS110 Class Application/User UART串口,串口配置参数:波特率为9600,8位数据位,无校验位,1位停止位,无流量控制;
在串口工具中发送数字“1”,则红灯被点亮;发送数字“2”,则绿灯被点亮;发送数字“3”,则蓝灯被点亮;发送其他ASCII字符,则RGB灯被熄灭。
///******************************************************************************
// *
// * MSP432P401
// * -----------------
// * | |
// * | |
// * | |
// * RST -| P1.3/UCA0TXD|----> PC
// * | |
// * | |
// * | P1.2/UCA0RXD|<---- PC
// * | |
// *
// *******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
/*
http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
*/
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, //选用SMCLK(1M)时钟源
6, // BRDIV = 6 ,clockPrescalar时钟分频系数
8, // UCxBRF = 8 firstModReg (BRDIV、UCxBRF、 UCxBRS和SMCLK,用于设置串口波特率)
17, // UCxBRS = 17 secondModReg
EUSCI_A_UART_NO_PARITY, // 校验位None
EUSCI_A_UART_LSB_FIRST, // 低位优先,小端模式
EUSCI_A_UART_ONE_STOP_BIT, // 停止位1位
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // 设置为过采样,该数值为1
};
int main(void)
{
/* 停用开门狗 */
MAP_WDT_A_holdTimer();
//![Simple FPU Config]
MAP_FPU_enableModule();/*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/
MAP_CS_setDCOFrequency(4000000);/* 设置DCO频率为指定频率,此处DCO=4M*/
MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置MCLK(主时钟,可用于CPU主频等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=4M*/
MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);/*设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO/4=1M*/
MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);/*设置SMCLK(低速子系统主时钟,可用TimerA频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/4=1M*/
//![Simple FPU Config]
/* 选用P1.2和P1.3使用UART模式 */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* 使用uartConfig配置UART_A0 */
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
/* 使能UART_A0 */
MAP_UART_enableModule(EUSCI_A0_BASE);
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT); /*使能UART_A0串口接收中断*/
MAP_Interrupt_enableInterrupt(INT_EUSCIA0); /*使能UART_A0中断*/
MAP_Interrupt_enableMaster(); /*使能中断总开关*/
//红灯
GPIO_setAsOutputPin(GPIO_PORT_P2,GPIO_PIN0); //设置P2.0为输出模式
GPIO_setOutputLowOnPin(GPIO_PORT_P2,GPIO_PIN0); //使LED2中红色灯初始为低电平(常暗)
//绿灯
GPIO_setAsOutputPin(GPIO_PORT_P2,GPIO_PIN1); //设置P2.1为输出模式
GPIO_setOutputLowOnPin(GPIO_PORT_P2,GPIO_PIN1); //使LED2中绿色灯初始为低电平(常暗)
//蓝灯
GPIO_setAsOutputPin(GPIO_PORT_P2,GPIO_PIN2); //设置P2.2为输出模式
GPIO_setOutputLowOnPin(GPIO_PORT_P2,GPIO_PIN2); //使LED2中蓝色灯初始为低电平(常暗)
while(1);
}
/*UART_A0中断函数*/
void EUSCIA0_IRQHandler(void)
{
char temp;
int i=0;
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); /*将UART_A0中断标志位的值赋值给status*/
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);/*清空UART_A0中断标志位*/
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) /*判断是否为UART_A0接受中断*/
{
temp=MAP_UART_receiveData(EUSCI_A0_BASE);
if(temp == '1')
{
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
//写代码控制led
}
else if(temp == '2')
{
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
//写代码控制led
}
else if(temp == '3')
{
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
//写代码控制led
}else{
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2);
//写代码控制led
}
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);
}
}
最低要求:打开工程09_03使用串口工具打开LaunchPad开发板XDS110 Class Application/User UART串口,串口配置参数:波特率为9600,8位数据位,无校验位,1位停止位,无流量控制;从任意起始时间开始以hh:mm:ss(24小时制,时分秒)格式进行计时并通过串口打印当前时间(1秒1次)。
进阶要求:提供串口命令来设置时分秒的初始值,完成设置后使用串口发送g(go)命令开始计时。
串口时钟
///******************************************************************************
// *
// * MSP432P401
// * -----------------
// * | |
// * | |
// * | |
// * RST -| P1.3/UCA0TXD|----> PC
// * | |
// * | |
// * | P1.2/UCA0RXD|<---- PC
// * | |
// *
// *******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
//打开微库 Options->Target->Code Generation->Use MicroLIB
//print函数调用fputc,通过串口发送到pc
int fputc(int ch, FILE *f)
{
MAP_UART_transmitData(EUSCI_A0_BASE, ch & 0xFF);
return ch;
}
/*
http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
*/
uint32_t hh = 0,mm = 0,ss = 0;
uint32_t seth = 0,setm = 0,sets = 0;
//根据代码逻辑自行初始化
uint32_t start = 1,flag = 1;
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, //选用SMCLK(1M)时钟源
6, // BRDIV = 6 ,clockPrescalar时钟分频系数
8, // UCxBRF = 8 firstModReg (BRDIV、UCxBRF、 UCxBRS和SMCLK,用于设置串口波特率)
17, // UCxBRS = 17 secondModReg
EUSCI_A_UART_NO_PARITY, // 校验位None
EUSCI_A_UART_LSB_FIRST, // 低位优先,小端模式
EUSCI_A_UART_ONE_STOP_BIT, // 停止位1位
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // 设置为过采样,该数值为1
};
int main(void)
{
/* 停用开门狗 */
MAP_WDT_A_holdTimer();
//![Simple FPU Config]
MAP_FPU_enableModule();/*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/
MAP_CS_setDCOFrequency(4000000);/* 设置DCO频率为指定频率,此处DCO=4M*/
MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置MCLK(主时钟,可用于CPU主频等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=4M*/
MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);/*设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO/4=1M*/
MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);/*设置SMCLK(低速子系统主时钟,可用TimerA频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/4=1M*/
//![Simple FPU Config]
/* 配置Timer32的第一个计数器为32位模式,周期模式,定时器频率=MCLK/定时器分频系数 此处第一个计数器频率=MCLK=4M */
MAP_Timer32_initModule(TIMER32_0_BASE, TIMER32_PRESCALER_1, TIMER32_32BIT,TIMER32_PERIODIC_MODE);
/* 使能Timer32第一个计数器中断开关*/
MAP_Interrupt_enableInterrupt(INT_T32_INT1);
MAP_Timer32_enableInterrupt(TIMER32_0_BASE);
MAP_Timer32_setCount(TIMER32_0_BASE,4000000); /*设置Timer32第一个计数器计数周期,此处 20M/10M=2s*/
MAP_Timer32_startTimer(TIMER32_0_BASE, false);/*Timer32第一个计数器以周期性模式开始计数*/
/* 选用P1.2和P1.3使用UART模式 */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* 使用uartConfig配置UART_A0 */
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
/* 使能UART_A0 */
MAP_UART_enableModule(EUSCI_A0_BASE);
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT); /*使能UART_A0串口接收中断*/
MAP_Interrupt_enableInterrupt(INT_EUSCIA0); /*使能UART_A0中断*/
MAP_Interrupt_enableMaster(); /*使能中断总开关*/
while(1){
if(start == 1 && flag == 1){
printf("%02d:%02d:%02d\r\n",hh,mm,ss);
flag = 0;
}
}
}
/*UART_A0中断函数 */
//进阶使用
int fh = 0, fm = 0, fs = 0;
int change[6] = {0};
int to_change = 0;
void EUSCIA0_IRQHandler(void)
{
char tmp = 0;
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); /*将UART_A0中断标志位的值赋值给status*/
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);/*清空UART_A0中断标志位*/
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) /*判断是否为UART_A0接受中断*/
{
tmp = MAP_UART_receiveData(EUSCI_A0_BASE);
//添加代码逻辑,发送h8m3s2g:表示将时间设置为08:03:02,g表示设置完成开始计时
switch(tmp)
{
case '1': case '2': case'3':
case '4': case '5': case '6':
case '7': case '8': case '9':case '0':
to_change *= 10;
to_change += (tmp - '0');
if(fh){seth = to_change;}
else if(fm){setm = to_change;}
else if(fs){sets = to_change;}
break;
case 'h':
fh = 1; fm = 0; fs = 0;
to_change = 0;
break;
case 'm':
fh = 0; fm = 1; fs = 0;
to_change = 0;
break;
case 's':
fh = 0; fm = 0; fs = 1;
to_change = 0;
break;
case 'g':
fh = fm = fs = 0;
hh = seth; mm = setm; ss = sets;
seth = setm = sets = 0;
to_change = 0;
break;
default:
break;
}
}
}
/* Timer32第一个计数器中断函数*/
//进行时钟计数处理(最低要求)
void T32_INT1_IRQHandler(void)
{
MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE); /*清除Timer32第一个计数器中断标志*/
//添加代码
MAP_Timer32_setCount(TIMER32_0_BASE, 4000000);
MAP_Timer32_startTimer(TIMER32_0_BASE, false);
ss++;
if(ss >= 60)
{
mm += ss / 60;
ss %= 60;
}
if(mm >= 60)
{
hh += mm / 60;
mm %= 60;
}
if(hh >= 24)
{
hh %= 24;
}
int temp = hh;
int array[] = {'0', '0'};
int cnt = 1;
while(temp)
{
int a = temp % 10;
temp /= 10;
array[cnt--] = a + '0';
}
for(int i = 0; i < 2; i++)
{
MAP_UART_transmitData(EUSCI_A0_BASE, array[i] & 0xFF);
}
MAP_UART_transmitData(EUSCI_A0_BASE, ':' & 0xFF);
temp = mm;
array[0] = array[1] = '0';
cnt = 1;
while(temp)
{
int a = temp % 10;
temp /= 10;
array[cnt--] = a + '0';
}
for(int i = 0; i < 2; i++)
{
MAP_UART_transmitData(EUSCI_A0_BASE, array[i] & 0xFF);
}
MAP_UART_transmitData(EUSCI_A0_BASE, ':' & 0xFF);
temp = ss;
array[0] = array[1] = '0';
cnt = 1;
while(temp)
{
int a = temp % 10;
temp /= 10;
array[cnt--] = a + '0';
}
for(int i = 0; i < 2; i++)
{
MAP_UART_transmitData(EUSCI_A0_BASE, array[i] & 0xFF);
}
MAP_UART_transmitData(EUSCI_A0_BASE, '\n' & 0xFF);
}