最近刚学了exynos4412,闲的无聊学下来,避免自己忘记了。
- 实验想法
串口:使用uart2
时钟使用mpll提供,所以得把其他用到mpll提供时钟的线路改为apll提供,并把apll修改成默认mpll的800mhz状态。主要修改CLK_MUX_STAT_DMC寄存器的第0,4,8位,修改值为1,使他使用SCLK_APLL时钟。
APLL & MPLL的倍频值:
设定对应寄存器的 P、M、S 三个值,不同的搭配最终频率不同,无须自 己计算,系统推荐的搭配如下:
2. 实验代码
定义一些需要用到的寄存器,和MPLL和APLL时钟的配置
#define CLK_SRC_DMC (*(volatile unsigned int *)0x10040000)
#define CLK_SRC_TOP1 (*(volatile unsigned int *)0x10030000)
#define CLK_DIV_PERIL0 (*(volatile unsigned int *)0x1003C550)
#define CLK_SRC_PERIL0 (*(volatile unsigned int *)0x11400000)
#define CLK_DIV_PERIL0 (*(volatile unsigned int *)0x1003C550)
#define MPLL_CON0 (*(volatile unsigned int *)0x10040108)
#define APLL_CON0 (*(volatile unsigned int *)0x10044100)
#define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10040000)
#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define MPLL_MDIV 0x64
#define MPLL_PDIV 0x3
#define MPLL_SDIV 0x0
#define APLL_MDIV 0x64
#define APLL_PDIV 0x3
#define APLL_SDIV 0x0
#define APLL_CON0_VAL set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_CON0_VAL set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)
串口2的初始化
/**********************************************************************
* @brief uart_init, Normal mode, No parity,One stop bit,8 data bits
* Buad-reate : 115200, clock srouce 100Mhz
* @param[in] int (ms)
* @return None
**********************************************************************/
void uart_init(void)
{
unsigned int baud,src_clock;//baud:波特率,src_clock:时钟频率
unsigned int div_val,div_val_1,div_val_2;//波特率的计算变量
baud=115200;//波特率:115200
src_clock=100;//时钟:100Mhz
div_val=10*src_clock*1000000 / (baud*16) -1;//计算出值
div_val_1=div_val/10;//取整数位
div_val_2=(div_val%10)*16/10;//取小数位
/*
* UART2 initialize
* Baud-rate 115200: src_clock:100Mhz
* DIV_VAL = (100*10^6 / (115200*16) -1) = (54.3 - 1) = 53.3
* UBRDIV2 = (Integer part of 53.3) = 53 = 0x35
* UFRACVAL2 = 0.3*16 = 0x5
* */
CLK_SRC_DMC|=(0X1<12);
CLK_SRC_TOP1|=(0X1<12);
CLK_SRC_PERIL0&=~(0Xf00);//修改时钟线
CLK_SRC_PERIL0|=(0X06<<8);
CLK_DIV_PERIL0&=~(0Xf00);
CLK_DIV_PERIL0|=(7<<8);//分频系数//8,100Mhz 800/8=100
GPA1.GPA1CON = (GPA1.GPA1CON & ~0xFF ) | (0x22); //GPA1_0:RX;GPA1_1:TX
UART2.ULCON2 = 0x3; //Normal mode, No parity,One stop bit,8 data bits
UART2.UCON2 = 0x5; //Interrupt request or polling mode
//UART2.UBRDIV2 = 0x35;
//UART2.UFRACVAL2 = 0x5;
UART2.UBRDIV2 = div_val_1;
UART2.UFRACVAL2 = div_val_2;
}
这个是自己修改时钟函数
void _sysclock(void)
{
MPLL_CON0=MPLL_CON0_VAL;//设置MPLL时钟频率
APLL_CON0=APLL_CON0_VAL;//800Mhz,设置APLL为800mhz
CLK_DIV_CPU0&=~(0x07<<24);//设置APLL分频系数
CLK_DIV_CPU0|=(0<24);//1分频
CLK_SRC_DMC|=(0x01<<8);//修改840位为1
CLK_SRC_DMC|=(0x01<<4);
CLK_SRC_DMC|=(0x01<<0);
}
串口接收发送代码
void putc(const char data)
{
while(!(UART2.UTRSTAT2 & 0X2));
UART2.UTXH2 = data;
if (data == '\n')
putc('\r');
}
void puts(const char *pstr)
{
while(*pstr != '\0')
putc(*pstr++);
}
unsigned char getchar()
{
unsigned char c;
while(!(UART2.UTRSTAT2 & 0X1));
c = UART2.URXH2;
putc(c);
return c;
}
主函数设置
/**********************************************************************
* @brief Main program body
* @param[in] None
* @return int
**********************************************************************/
int main(void) {
char c, str[] = "uart test2233388!! \n";
_sysclock();
//LED
GPX2.GPX2CON = 0x1 << 28;
uart_init();
while(1)
{
//Turn on LED
GPX2.GPX2DAT = GPX2.GPX2DAT | 0x1 << 7;
//puts(str);
// c=getchar()+1;
// if(!(UART2.UTRSTAT2 & 0X1))
// putc(c);
getchar();
mydelay_ms(500);
//Turn off LED
GPX2.GPX2DAT = GPX2.GPX2DAT & ~(0x1 << 7);
mydelay_ms(500);
}
return 0;
}
4.后面是烧写代码的方式
clean工程,重新编译,按debug烧写
我就是怕自己忘记怎么操作了,所以写的这些,仅供参考,如果哪里不好欢迎指出,我也刚在学