工程建立步骤:
main函数结构
int main(){
Device_Init(); //不要动
//添加你的其他初始化代码
while(1){//工作循环
//添加需要一直需要做的工作代码,如显示等
}
return 1;
}
可以看出来,主函数的结构和一般嵌入式系统的主函数一样,首先是初始化工作,这里只不过添加了一个Device_Init()函数,一般该函数我们不需要修改,在该函数之后我们要添加一下我们具体工作的初始化工作代码;随后是一个死循环,其中主要放置周期性的、有规范性的或查询等工作,一般我们将显示部分放置其中。另外程序结构还有一部分就是中断,我们所有的模板已经将中断服务功能抽出来放到了ISR.C中了,我们可以在此修改。我们也可以不要模板,直接从main函数的第一行写,这也是可以的。
void Device_Init()
{
SetPll();//设置PLL的,不要动
//IRQ_Disable();
GPIO_Init();//可能有得较多,具体内容根据需要到该函数中设定
//IRQ_Init();
//SetSysTick();
//PWM_Init();
//ADC_Init();
//OPA0_Init();
//OPA2_Init();
//CMP0_Init();
//Uart0_Init();//初始化串口的,数据格式、波特率到此设定
//IRQ_Enable();//使能中断的,具体使能哪些中断,可以到该函数中设定
}
Device_Init()一般我们要按需选择,注释掉不需要的。从代码中也可以看出主要涉及的是关于片上设备的选择问题。我们按需修改,并在其下添加片外设备的初始化代码。
查看函数的定义:
以查看Device_Init为例,选中函数名Device_Init,右击,出现浮动窗,如下图,选中Go to Defiition of ‘Device_Init’,系统自动跳转到Device_Init
常用的位操作技巧
//有用的技巧
//将某个变量(或寄存器)PA的i,j位置1:
PA |= ((1<
C语言操作外设:
对目前大部分的MCU来说,操作外设就是对特定的寄存器进行读写操作。一般外设的寄存器被映射到系统存储器空间,它们可以通过指针进行访问。使用微控制器供应商提供的设备驱动,可以简化开发任务,并且增强软件在不同平台之间的可移植性。如果需要直接访问外设寄存器,可以使用以下方法:
1
LK32T102的管脚
LK32T102内部设备功能较多,而管脚较少,所以基本上每一个管脚都是多功能的,基本上可以分为两大类:数字端口和模拟端口两大类,如下图所示:
此信息可以从编程信息手册中查出。
因为管脚功能较多,则一定有用于管脚功能选择的寄存器,这个基本对应着CFGx寄存器,每一个端口涉及32个配置寄存器CFGx(x=0~31),对应32个管脚,但是实际只用到16个。
GPIO口操作
有3个端口,分别为PA,PB,PC,每个端口可以有32条口线,但是实际PA,PB可能只用到16个,PC更少。
2个管脚值寄存器(1个管脚值寄存器PIN(只读)和管脚输出寄存器OUT(读写)),1个管脚输出使能OUTEN,1个管脚置位OUTSET,1个管脚清零OUTCLR
操作的方法有两种:
1)直接操作寄存器 ---->有关定义在SC32F5832.H
如使能PA端口的PA0~PA8可以如下操作:
PA->OUTEN=0x000000FF;
上述代码中PA表示端口PA,OUTEN表示寄存器OUTEN,其他类似
2)借助已定义的宏------>有关定义在GPIO.H
如实现上述代码的同样功能:
PA_OUT_ENABLE(0);
PA_OUT_ENABLE(1);
....
PA_OUT_ENABLE(8);
具体可以查阅GPIO.H,有非常详细的解释。建议直接操作寄存器。
这两个头文件已经包含在模板中了,一般不需要我们过多的设置。
深入系统初始化
在我们的工程模板中,main函数调用了Device_Init();Device_Init()又调用了很多基本设备的初始化工作:
void Device_Init()
{
SetPll();
//IRQ_Disable();
GPIO_Init();
IRQ_Init();
//SetSysTick();
//PWM_Init();
//ADC_Init();
//OPA0_Init();
//OPA2_Init();
//CMP0_Init();
Uart0_Init();//
//IRQ_Enable();//
}
上述的意义很明确,一般不需要修改;其中的GPIO_Init()就是关于GPIO的初始化的,我们可以进行基本的初始化工作:
void GPIO_Init()
{
// GPIO_AF_SEL(DIGITAL,PA,8,2); // PWM1A
// GPIO_AF_SEL(DIGITAL,PA,9,2); // PWM2B
// GPIO_AF_SEL(DIGITAL,PA,10,2); // PWM2A
// GPIO_AF_SEL(DIGITAL,PB,13,2); // PWM0B
// GPIO_AF_SEL(DIGITAL,PB,14,2); // PWM0A
// GPIO_AF_SEL(DIGITAL,PB,15,2); // PWM1B
//
// GPIO_AF_SEL(DIGITAL,PA,11,7); // TIM_CH1
// GPIO_AF_SEL(DIGITAL,PA,12,7); // TIM_CH1N
// GPIO_AF_SEL(DIGITAL,PB,12,4); // TIM_BKIN
//
// GPIO_AF_SEL(DIGITAL,PB,2,5); // PB2
//
// GPIO_AF_SEL(ANALOGY,PB,11,0); // ADCB6
// GPIO_AF_SEL(ANALOGY,PC,13,0); // ADCB7
//
// GPIO_AF_SEL(ANALOGY,PA,0,0); // OPA0P
//
// GPIO_AF_SEL(ANALOGY,PB,0,0); // OPA2P
//
// GPIO_AF_SEL(DIGITAL,PB,8,5); // TIM_CH2
// GPIO_AF_SEL(DIGITAL,PB,9,5); // TIM_CH2N
// GPIO_AF_SEL(DIGITAL,PC,0,1); // TIM_CH3
// GPIO_AF_SEL(DIGITAL,PB,1,6); // TIM_CH3N
//
// GPIO_AF_SEL(DIGITAL,PC,6,3); // PC6
// GPIO_AF_SEL(DIGITAL,PA,15,3); // PA15
GPIO_AF_SEL(DIGITAL, PA, 2, 1); // PA2
GPIO_AF_SEL(DIGITAL, PA, 3, 1); // PA3
//PB0 - PB7 -> LED1 - LED8
GPIO_AF_SEL(DIGITAL, PB, 0, 0); // LED1 - D9
GPIO_AF_SEL(DIGITAL, PB, 1, 0); // LED2 - D10
GPIO_AF_SEL(DIGITAL, PB, 2, 0); // LED3 - D11
GPIO_AF_SEL(DIGITAL, PB, 3, 0); // LED4 - D12
GPIO_AF_SEL(DIGITAL, PB, 4, 0); // LED5 - D13
GPIO_AF_SEL(DIGITAL, PB, 5, 0); // LED6 - D14
GPIO_AF_SEL(DIGITAL, PB, 6, 0); // LED7 - D15
GPIO_AF_SEL(DIGITAL, PB, 7, 0); // LED8 - D16
//PB8 - PB15 ->
GPIO_AF_SEL(DIGITAL, PB, 8, 0); // R1
GPIO_AF_SEL(DIGITAL, PB, 9, 0); // R2
GPIO_AF_SEL(DIGITAL, PB, 10, 0); // R3
GPIO_AF_SEL(DIGITAL, PB, 11, 0); // R4
GPIO_AF_SEL(DIGITAL, PB, 12, 0); // C1
GPIO_AF_SEL(DIGITAL, PB, 13, 0); // C2
GPIO_AF_SEL(DIGITAL, PB, 14, 0); // C3
GPIO_AF_SEL(DIGITAL, PB, 15, 0); // C4
// PA0 -> SB1 PA1 -> SB2 PA10 -> SB3 PA11 -> SB4
GPIO_AF_SEL(DIGITAL, PA, 0, 0); //
GPIO_AF_SEL(DIGITAL, PA, 1, 0); //
GPIO_AF_SEL(DIGITAL, PA, 10, 0); //
GPIO_AF_SEL(DIGITAL, PA, 11, 0); //
//
GPIO_PUPD_SEL(PUPD_NULL, PA, 0 );
GPIO_PUPD_SEL(PUPD_NULL, PA, 1 );
GPIO_PUPD_SEL(PUPD_NULL, PA, 10 );
GPIO_PUPD_SEL(PUPD_NULL, PA, 11 );
//
GPIO_PUPD_SEL(PUPD_NULL, PB, 8 );
GPIO_PUPD_SEL(PUPD_NULL, PB, 9 );
GPIO_PUPD_SEL(PUPD_NULL, PB, 10 );
GPIO_PUPD_SEL(PUPD_NULL, PB, 11 );
//
GPIO_AF_SEL(DIGITAL, PA, 12, 0); //
//PWM
//GPIO_AF_SEL(DIGITAL, PA, 7, 3);// T0CH2
PA_OUT_ENABLE(7);
//
GPIO_AF_SEL(DIGITAL, PB, 14, 0);
GPIO_PUPD_SEL(PUPD_NULL, PB, 14);
//
GPIO_AF_SEL(DIGITAL, PA, 6, 3);// T0CH1
GPIO_PUPD_SEL(PUPD_NULL, PA, 6);
}
这两处可能是我们会用掉的,在这里我们只需要选择相应的功能即可。
/*
上述代码中的的函数GPIO_AF_SEL(uint8_t AD,PA_Type* GPIOx,uint8_t gpiopin,uint8_t fun_num)表示GPIO管脚功能选择.
AD 第一个参数代表处理数字量还是模拟量,DIGITAL ANALOGY
GPIOx 第二个参数代表端口,PA PB PC
gpiopin 第三个参数代表管脚,0~31
fun_num 第4个参数代表功能,0~7
管脚及功能要查编程手册P20
*/
除非有配置管脚新功能,我们不要动Device_Init()和GPIO_Init(),有关的配置直接在main.c的main函数中配置。
/****************************************/
很遗憾,有很多的东西我没有办法一一给大家回复,所以我建立了一个群,供大家一起交流!