本帖最后由 JackTang1994 于 2021-9-3 13:08 编辑
#技术资源# #申请原创#
参考资料
AVR内核指令集:
https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf
ATmega4809芯片数据手册:
https://www.microchip.com/content/dam/mchp/documents/MCU08/ProductDocuments/DataSheets/ATmega4808-09-DataSheet-DS40002173C.pdf
需求
使用内部20M时钟,并将其分频为10MHZ
此**中的例程下载
ATMEGA4809_CLOCK.zip
(45.17 KB)
查看芯片启动说明
打开芯片数据手册查看,AVR内核章节。了解芯片启动流程以及需要的一些资源
从手册中我们可以得到芯片复位后,直接从Flash最低地址(0x0000)处获取指令并执行。而栈顶地址指向SRAM的最高地址(0x3FFF)处
查看时钟树
查看手册中时钟部分,了解整个MCU时钟是如何分配的,这样在操作外设时才能知道哪些时钟需要配置且如何配置。
这里我们使用内部16/20M时钟给外设提供时钟。
配置时钟
查看时钟的overview,了解整个时钟基本信息。从这个里我们可以知道外设的时钟不需要单独开启,这个和STM32芯片不一样。其实从时钟树图也可以看出来,分频后的时钟直接就到外设了。
查看时钟配置相关寄存器
MCLKCTRLA寄存器控制时钟源的选择,我们这里选择16/20M内部晶振作为时钟源。
问题:我们这个寄存器的属性处可以看到它是Configuration Change Protection(配置修改保护),我们继续查看手册找到Configuration Change Protection相关说明。
CCP(Configuration Change Protection)
说明:系统一些关键寄存器被保护了,不能随便修改。如果非常修改需要对这个CCP寄存器写入特定的KEY才能解锁,这里才能操作被保护的寄存器。
编写代码
protected_write_io(addr, CCP_IOREG_gc, value); //调用汇编实现的函数protected_write_io,在工程中的protected_io.S文件。
protected_io.S文件代码:
PUBLIC_FUNCTION(protected_write_io)
movw r30, r24 // Load addr into Z
out CCP, r22 // Start CCP handshake
st Z, r20 // Write value to I/O register
ret // Return to caller
调试代码
1. 设置工程
配置工程为Simulator,使用模拟调试器进行代码调试
2. 调试工具使用
点击I/O View,然后找到时钟部分。查看时钟相关寄存器时否被改变了
备注:
修改代码,不用protected_io.S中的汇编来实现时钟配置,而有采用C语言。后面会发现I/O View中的时钟寄存器不会变化,这里由于时钟相关配置的寄存器被保护了,使用C代码无法做到4条指令实现时钟配置,所以就会没有效果。
// 需要配置时钟需要解锁:Configuration Change Protection(P35)
// 频率10MHZ
void System_CLCK_Init(void)
{
uint8_t i = 4;
CPU_CCP = 0XD8; // 解锁IOREG
while(!(CPU_CCP & 0x01));
//while(i--);
CLKCTRL.MCLKCTRLA = 0x00; // 16/20 MHz内部晶振
CLKCTRL.MCLKCTRLB |= (0x01 << 0); // 使能分频
CLKCTRL.MCLKCTRLB &= ~(0x0F << 1); // 2分频
FUSE.OSCCFG = 0x01; // 将16/20M时钟源选择为20M
}
|