LP-MSPM03507学习资料汇总

(因对MSPM0研究不够深入,故暂不开启浏览权限,权当记录学习。但愿尽快掌握供大家免费阅读。有意者可私信我共同学习)

一、延时函数

1、官方延时函数

1.1 SysConfig配置

a5d5f12cf45c4bbfbcb74c79480c7316.png

1.2 重定义延时函数

 bae26b5ca80548d9b2674537e7309dc1.png

1.3 代码填写

int main(void)
{
    SYSCFG_DL_init();
    while (1) {
        /*翻转PA0的输出*/
        DL_GPIO_togglePins(GPIO_GRP_0_PORT,GPIO_GRP_0_LED_PIN);
        delay_cycles(1600000);
    }
}

2、自定义延时函数

void delay_ms(uint32_t ms)
{
    while(ms--)
        delay_cycles(CPUCLK_FREQ/1000);
}

二、GPIO口操作之点亮LED

1、命名、配置输出

2、配置上下拉,绑定引脚

快速绑定LED引脚

3.代码填写

实现效果:LED以一秒周期进行三色闪烁

    while (1) {
        DL_GPIO_setPins(GPIO_LED_PORT, GPIO_LED_PIN_BLUE_PIN);
        delay_ms(500);
        DL_GPIO_clearPins(GPIO_LED_PORT, GPIO_LED_PIN_BLUE_PIN);
        delay_ms(500);

        DL_GPIO_setPins(GPIO_LED_PORT, GPIO_LED_PIN_GREEN_PIN);
        delay_ms(500);
        DL_GPIO_clearPins(GPIO_LED_PORT, GPIO_LED_PIN_GREEN_PIN);
        delay_ms(500);

        DL_GPIO_setPins(GPIO_LED_PORT, GPIO_LED_PIN_RED_PIN);
        delay_ms(500);
        DL_GPIO_clearPins(GPIO_LED_PORT, GPIO_LED_PIN_RED_PIN);
        delay_ms(500);
    }

三、按键中断

1)配置名称、输出、上下拉、按键滤波

2)配置中断为下降沿

3) 代码填写
int main(void)
{
    SYSCFG_DL_init();
        
    NVIC_EnableIRQ(GPIO_KEY_INT_IRQN);                                //开启中断
    while (1) {

    }
}
 
void GROUP1_IRQHandler(void)
{
    switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
        case GPIO_KEY_INT_IIDX:                                         //检测到中断翻转PA0电平
            DL_GPIO_togglePins(GPIO_LED_PORT, GPIO_LED_PIN_BLUE_PIN);    //翻转电平
        break;
    }
}

四、Timer定时器

1、定时器中断

1)Timer命名及分频

2)设置定时器周期及中断配置

3)代码填写
int main(void)
{
    SYSCFG_DL_init();
    /*使能定时器中断*/
    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
    /*使能定时器计数*/
    DL_TimerA_startCounter(TIMER_0_INST);
    while (1) {
        // DL_GPIO_togglePins(GPIO_LED_PORT,GPIO_LED_PIN_BLUE_PIN);
        // delay_ms(500);
    }
}
/*定时器中断服务函数*/
void TIMER_0_INST_IRQHandler(void)
{
    switch (DL_TimerA_getPendingInterrupt(TIMER_0_INST)) {
    case DL_TIMERA_IIDX_ZERO:
    /*定时器计数完成进入中断翻转LED灯的电平*/
        DL_GPIO_togglePins(GPIO_LED_PORT,GPIO_LED_PIN_BLUE_PIN);
    break;
    default:
    break;
    }
}

2、定时器生成PWM波

1)定时器初始化配置

2)填写ARR,CCR及占空比数值 

3)改变频率、占空比封装函数
/* 
    函数功能:Set_Duty()设定指定定时器指定通道的占空比
    参数:   
        PWMA:       指定定时器名称  PWM_0_INST
        Channel:    指定定时器通道  DL_TIMER_CC_0_INDEX / DL_TIMER_CC_1_INDEX
        ARR:        定时器重装载值
        duty:      设定占空比      归一化的占空比(0 ~ 1)
 */
void Set_Duty(GPTIMER_Regs * PWMA, DL_TIMER_CC_INDEX Channel, int ARR, float duty)
{
    uint32_t CompareValue;
    CompareValue = ARR - ARR * duty;
    DL_Timer_setCaptureCompareValue(PWMA, CompareValue, Channel);
}


/* 
    函数功能:Set_Freq()设定指定定时器频率
    参数:   
        PWMA:       指定定时器名称  PWM_0_INST
        CLK_FREQ:   定时器总线频率  PWM_0_INST_CLK_FREQ
        freq:      设定频率值      
 */
void Set_Freq(GPTIMER_Regs *PWMA , uint32_t CLK_FREQ, uint32_t freq)
{
    uint32_t period;
    period = CLK_FREQ / freq;
    DL_Timer_setLoadValue(PWMA, period);
}

4)main.c调用
int main(void)
{
    SYSCFG_DL_init();
    DL_Timer_startCounter(PWM_0_INST);                  //开启PWM波

    Set_Freq(PWM_0_INST,PWM_0_INST_CLK_FREQ,5000);      //改变频率为 5000Hz
    Set_Duty(PWM_0_INST,DL_TIMER_CC_0_INDEX,3200,0.5);  //设置PWM0的通道0的占空比为50%
    while (1) {
    }
}

六、DAC

1、DAC输出直流电压

1)使能DAC时钟

2) 配置DAC输出电压

3)输入输出配置

4)代码填写
int main(void)
{
    SYSCFG_DL_init();
    
    DL_DAC12_output12(DAC0, 3000);    //输出电压值 = 3000 / 4096 *3.3 V
    DL_DAC12_enable(DAC0);
    while (1) {
       
    }
}

2、DAC+FIFO+TIMER输出指定波形

1)DAC触发时钟配置

2)相关配置

3)配置FIFO

4)配置中断、事件

5)代码填写
int i = 0;
uint32_t data[32] = {2048, 2447, 2831, 3185, 3496, 3750,
3940, 4056, 4095, 4056, 3940, 3750, 3496, 3185, 2831, 2447, 2048, 1648,
1264, 910, 599, 345, 155, 39, 0, 39, 155, 345, 599, 910, 1264, 1648};;

int main(void)
{
    SYSCFG_DL_init();
    /* 使能计时器以触发DAC */
    DL_Timer_startCounter(TIMER_0_INST);
    /* 使能DAC中断以更新DAC输出 */
    NVIC_EnableIRQ(DAC12_INT_IRQN);
    /*
    * 发送信号至DAC输出.
    * 定时器的触发周期可以在Sysconfig中进行配置。
    * 信号频率将会取决于 sample time generator 和 number of samples:
    */
    while (1) {
    }
}


/*
* DL_DAC12_IIDX_FIFO_1_2_EMPTY即为我们选择的FIFO半满中断。
*/
void DAC12_IRQHandler(void)
{
    switch (DL_DAC12_getPendingInterrupt(DAC0)) {
        case DL_DAC12_IIDX_FIFO_1_2_EMPTY:
        i = (i>32)?0:i+1;
        DL_DAC12_output12(DAC0, data[i]);
        break;
        default:
        break;
    }
}

3、DAC+FIFO+DMA输出指定波形

1)初始化配置

2)DMA配置

3)中断、FIFO配置

4)代码填写

/* 正弦波样本数据 */
const uint16_t gOutputSignalSine64[] = {2048, 2248, 2447, 2642, 2831, 3013,
3185, 3347, 3496, 3631, 3750, 3854, 3940, 4007, 4056, 4086, 4095, 4086,
4056, 4007, 3940, 3854, 3750, 3631, 3496, 3347, 3185, 3013, 2831, 2642,
2447, 2248, 2048, 1847, 1648, 1453, 1264, 1082, 910, 748, 599, 464, 345,
241, 155, 88, 39, 9, 0, 9, 39, 88, 155, 241, 345, 464, 599, 748, 910, 1082,
1264, 1453, 1648, 1847};
int main(void)
{
    SYSCFG_DL_init();
    /* 设置DMA的源地址,目标地址,传输大小 */
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gOutputSignalSine64[0]);        //这里源地址是正弦
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) & (DAC0->DATA0));                //这里目标地址是DAC的DAT
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, sizeof(gOutputSignalSine64) / sizeof(uint16_t));
    /* 使能DMA通道 */
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    while (1) {
    }
}

七、ADC


1、单通道ADC单次中断配置

1)配置读取模式、触发模式

2)配置存储区域、绑定引脚

3)配置采样周期、开启中断

4)填写代码
volatile bool ADC_Flag;        //ADC读取标志位
volatile uint16_t ADC_Val;     //ADC读取数值

int main(void)
{
    SYSCFG_DL_init();
    
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);             //启动中断

    while (1) {
        ADC_Flag = false;
        DL_ADC12_startConversion(ADC12_0_INST);        //启动转换

        while(ADC_Flag == false);                      //等待转换

        ADC_Val = DL_ADC12_getMemResult(ADC12_0_INST,DL_ADC12_MEM_IDX_0);    //读取数值
        DL_ADC12_enableConversions(ADC12_0_INST);                            //重新开启中断
    }
}


void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {            //中断接收函数
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            ADC_Flag = true;
            break;
        default:
            break;
    }
}

2、单通道ADC轮询读取配置

1)使能重复采样模式

2)设置周期及中断

3)代码填写
volatile bool ADC_Flag;        //ADC读取标志位
volatile uint16_t ADC_Val;     //ADC读取数值
 
int main(void)
{
    SYSCFG_DL_init();
    
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);                  //启动中断
    DL_ADC12_enableConversions(ADC12_0_INST); 
    ADC_Flag = false;
    DL_ADC12_startConversion(ADC12_0_INST);                 //启动转换
    
    while (1) {
        // while(ADC_Flag == false);                        //等待转换
    }
}
 
 
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {            //中断接收函数
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            ADC_Val = DL_ADC12_getMemResult(ADC12_0_INST,DL_ADC12_MEM_IDX_0);    //读取数值
            ADC_Flag = true;
            break;
        default:
            break;
    }
}

3、单通道ADC+DMA传输

1)初始化配置

2)中断配置

3)DMA配置

4)代码填写
#define ADC_SAMPLE_SIZE (1024)
uint16_t ADC_Val[ADC_SAMPLE_SIZE];
volatile bool ADC_Flag;

int main(void)
{
    SYSCFG_DL_init();
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID,(uint32_t)&(ADC0->ULLMEM.MEMRES[0]));    //设置DMA源地址
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&ADC_Val[0]);                //设置DMA目标地址
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_SAMPLE_SIZE);                  //设置DMA传输长度
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);                                     //使能DMA通道

    /* Setup interrupts on device */
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);                                          //使能ADC中断
    DL_ADC12_enableDMA(ADC12_0_INST);                                               //使能ADC的DMA传输
    DL_ADC12_startConversion(ADC12_0_INST);                                         //开启ADC传输
    ADC_Flag = false;
    while (1) {
        // while (false == ADC_Flag);
        // ADC_Flag = false;//标志位清零
    }
}


/*
* 中断的意义在于能够使程序在DMA数据传输完成之后
* 才开始下一次数据接收,能够使DMA传输更加稳定
*/
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_DMA_DONE:
            ADC_Flag = true;
        break;
        default:
        break;
    }
}

4、多通道ADC配置

1)

2)

3)

4)代码填写
volatile bool ADC_Flag;
volatile uint16_t ADC_Val0, ADC_Val1;

int main(void)
{
    SYSCFG_DL_init();
    
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);                //开启第一个通道ADC中断

    while (1) {
        ADC_Flag = false;
        DL_ADC12_startConversion(ADC12_0_INST);

        while(ADC_Flag == false);

        ADC_Val0 = DL_ADC12_getMemResult(ADC12_0_INST,DL_ADC12_MEM_IDX_0);
        ADC_Val1 = DL_ADC12_getMemResult(ADC12_0_INST,DL_ADC12_MEM_IDX_1);
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}


void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_MEM1_RESULT_LOADED:            //判断最后一路通道ADC中断
            ADC_Flag = true;
            break;
        default:
            break;
    }
}

八、UART串口通信

1)串口速率配置

2)配置收发方式

3)开启接收中断

4)填写代码
uint8_t gEchoData;

int main(void)
{
    SYSCFG_DL_init();
    
    NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);            //清除标志位
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);                  //启动串口接收中断

    while (1) {
       
    }
}

void UART_0_INST_IRQHandler(void)
{
    gEchoData = DL_UART_Main_receiveData(UART_0_INST);    //读取上位机发送数据
    DL_UART_Main_transmitData(UART_0_INST,gEchoData);     //传输数据
}

5)串口重定向
#include "stdio.h"
#include "string.h"

int fputc(int c, FILE* stream)
{
	DL_UART_Main_transmitDataBlocking(UART_0_INST, c);
    return c;
}

int fputs(const char* restrict s, FILE* restrict stream)
{
    uint16_t i, len;
    len = strlen(s);
    for(i=0; i<len; i++)
        DL_UART_Main_transmitDataBlocking(UART_0_INST, s[i]);
    return len;
}

int puts(const char *_ptr)
{
    int count = fputs(_ptr, stdout);
    count += fputs("\n", stdout);
    return count;
}

九、修改CPU主频

1)开启时钟树

2)改变倍频

十、OLED配置

1、软件模拟IIC

1)路径添加

2)引脚配置

3)代码填写
#include "oled.h"
#include "bmp.h"

int main( void )
{
    SYSCFG_DL_init();
    
    uint8_t t=' ';
    OLED_Init();		//初始化OLED
    while(1) 
    {		
        OLED_DrawBMP(0,0,128,64,BMP1);
        delay_ms(500);
        OLED_Clear();
        OLED_ShowChinese(0,0,0,16);//中
        OLED_ShowChinese(18,0,1,16);//景
        OLED_ShowChinese(36,0,2,16);//园
        OLED_ShowChinese(54,0,3,16);//电
        OLED_ShowChinese(72,0,4,16);//子
        OLED_ShowChinese(90,0,5,16);//科
        OLED_ShowChinese(108,0,6,16);//技
        OLED_ShowString(8,2,(uint8_t *)"ZHONGJINGYUAN",16);
        OLED_ShowString(20,4,(uint8_t *)"2014/05/01",16);
        OLED_ShowString(0,6,(uint8_t *)"ASCII:",16);  
        OLED_ShowString(63,6,(uint8_t *)"CODE:",16);
        OLED_ShowChar(48,6,t,16);
        t++;
        if(t>'~')t=' ';
        OLED_ShowNum(103,6,t,3,16);
        delay_ms(500);
        OLED_Clear();
    }
}

M0G3507软件模拟IIC

2、硬件IIC

1)初始化配置

2)中断配置

M0G3507硬件IIC

十一、MPU6050

M0G3507MPU6050

十二、编码器引脚中断四分频模式

1、配置引脚

2、中断配置

 PIN_1配置同理

3、定时器配置

4、配置周期及中断

5、代码填写 
volatile uint32_t EncoderA_Port, EncoderB_Port;         //编码器端口
volatile int32_t EncoderA_CNT = 0, EncoderB_CNT = 0;    //编码器计数值
volatile int32_t EncoderA_VEL = 0, EncoderB_VEL = 0;    //马达速度

/*
    * 编码器读取函数
    * 编码器A、B分别对应编码器A、B的引脚
    * EncoderA_CNT、EncoderB_CNT    分别对应编码器A、B的计数值
    * EncoderA_Port、EncoderB_Port  分别对应编码器A、B的端口
*/
void Encodering(void)
{
    EncoderA_Port = DL_GPIO_getEnabledInterruptStatus(GPIO_EncoderA_PORT, GPIO_EncoderA_PIN_0_PIN | GPIO_EncoderA_PIN_1_PIN);
    EncoderB_Port = DL_GPIO_getEnabledInterruptStatus(GPIO_EncoderB_PORT, GPIO_EncoderB_PIN_2_PIN | GPIO_EncoderB_PIN_3_PIN);
    
    /* 编码器A */
    if((EncoderA_Port & GPIO_EncoderA_PIN_0_PIN) == GPIO_EncoderA_PIN_0_PIN)        //编码器A-Pin0
    {
        if(!DL_GPIO_readPins(GPIO_EncoderA_PORT,GPIO_EncoderA_PIN_1_PIN))   EncoderA_CNT--;
        else                                                                EncoderA_CNT++;
    }
    else if((EncoderA_Port & GPIO_EncoderA_PIN_1_PIN) == GPIO_EncoderA_PIN_1_PIN)   //编码器A-Pin1
    {
        if(!DL_GPIO_readPins(GPIO_EncoderA_PORT,GPIO_EncoderA_PIN_0_PIN))   EncoderA_CNT++;
        else                                                                EncoderA_CNT--;
    }
    DL_GPIO_clearInterruptStatus(GPIO_EncoderA_PORT, GPIO_EncoderA_PIN_0_PIN|GPIO_EncoderA_PIN_1_PIN);


    /* 编码器B */
    if((EncoderB_Port & GPIO_EncoderB_PIN_2_PIN) == GPIO_EncoderB_PIN_2_PIN)
    {
        if(!DL_GPIO_readPins(GPIO_EncoderB_PORT,GPIO_EncoderB_PIN_3_PIN))   EncoderB_CNT--;
        else                                                                EncoderB_CNT++;
    }
    else if((EncoderB_Port & GPIO_EncoderB_PIN_3_PIN) == GPIO_EncoderB_PIN_3_PIN)
    {
        if(!DL_GPIO_readPins(GPIO_EncoderB_PORT,GPIO_EncoderB_PIN_2_PIN))   EncoderB_CNT++;
        else                                                                EncoderB_CNT--;
    }
    DL_GPIO_clearInterruptStatus(GPIO_EncoderB_PORT, GPIO_EncoderB_PIN_2_PIN|GPIO_EncoderB_PIN_3_PIN);
}



/**************************************************************************
Function: Read encoder count per unit time
Input   : TIMX:Timer
Output  : none
函数功能:单位时间读取编码器计数
入口参数:TIMX:定时器
返回  值:速度值
**************************************************************************/
void Read_Encoder(void)
{
    EncoderA_VEL = EncoderA_CNT;
    EncoderA_CNT = 0;
    EncoderB_VEL = EncoderB_CNT;
    EncoderB_CNT = 0;
}



/*
    * 编码器中断服务函数
*/
void GROUP1_IRQHandler(void)
{
    /* 运行编码器 */
    Encodering();
}


/*
    * 编码器读取中断服务函数
    * 读取编码器数值
*/
void TIMER_Encoder_Read_INST_IRQHandler(void)
{
    switch (DL_TimerG_getPendingInterrupt(TIMER_Encoder_Read_INST)){
        case DL_TIMER_IIDX_ZERO:
            Read_Encoder();            //赋值编码器数值
            break;
        default:
            break;
    }
}

M0G3507四分配编码器模式

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值