Microchip SAM E70 X PLAINED ULTRA开发板快速上手——IIC、SPI、PWM
由于项目需要开始接触Microchip(原Atmel)家的这款MCU,使用工具是SAM E70 X PLAINED ULTRA开发板。本系列用于记录从0开始一步步熟悉这款MCU的开发过程。开发板外设资源丰富,之前一直是使用HAL库开发ST/GD系列的MCU,Microchip的开发风格与前两者存在一定差异,借此机会巩固一下基础知识。
上篇学习了GPIO、UART的简单使用,本章讲学习使用IIC、SPI、PWM等常见外设。
- ATSAME70Q21B Microcontroller
- Cortex-M7 Core-based Microcontroller
- Max Speed: 300MHz
- Flash: 2048KB

IIC主机
IIC协议简要回顾

起始信号、结束信号等概念不再展开介绍。
IIC写
开发板上自带一块EEPROM(AT24),设备地址0x57。在图形界面中使能IIC(TWIHS)
配置IIC,主机模式,400kHz
配置完成后,修改main函数,代码如下:
uint8_t hello_str[] = "hello from the SAM E70 X PLAINED ultra";
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
printf("%s at %s %s\r\n", hello_str, __DATE__, __TIME__);
TWIHS0_Write(0x57, hello_str, sizeof(hello_str));
while ( true )
{
LED3_Toggle();
SYSTICK_DelayMs(500);
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
使用逻辑分析仪抓取波形,效果如下:
IIC从机
开发板具有三个IIC外设,选择IIC2作为从机(三个IIC都可以根据需要设置为主机或从机),图形设置如下:
这里我们设置从机地址为0x54。同时使用一块STM32作为IIC主机与开发板通信,STM32的配置这里不做介绍。
与主机不同的是,从机生成的库文件只实现了中断代码,并未实现具体的回调函数需要手动注册。
初始化代码如下:
void TWIHS2_Initialize( void )
{
/* Reset the TWIHS Module */
TWIHS2_REGS->TWIHS_CR = TWIHS_CR_SWRST_Msk;
/* Disable the TWIHS Master/Slave Mode */
TWIHS2_REGS->TWIHS_CR = TWIHS_CR_MSDIS_Msk | TWIHS_CR_SVDIS_Msk;
/* Configure slave address */
TWIHS2_REGS->TWIHS_SMR = TWIHS_SMR_SADR(0x54);
/* Clear the Transmit Holding Register and set TXRDY, TXCOMP flags */
TWIHS2_REGS->TWIHS_CR = TWIHS_CR_THRCLR_Msk;
/* Initialize the TWIHS PLIB Object */
/* Enable interrupt for Slave Access and End of Slave Access */
TWIHS2_REGS->TWIHS_IER = TWIHS_IER_SVACC_Msk | TWIHS_IER_EOSACC_Msk;
twihs2Obj.callback = NULL;
twihs2Obj.isBusy = false;
twihs2Obj.isFirstTxPending = false;
twihs2Obj.isAddrMatchEventNotified = false;
/* Enable Slave Mode */
TWIHS2_REGS->TWIHS_CR = TWIHS_CR_SVEN_Msk;
TWIHS2_CallbackRegister(TWIHS2_SlaveCallback, 0);//手动调用,其中TWIHS2_SlaveCallback需自行实现
}
void TWIHS2_CallbackRegister(TWIHS_SLAVE_CALLBACK callback, uintptr_t contextHandle)
{
twihs2Obj.callback = callback;
twihs2Obj.context = contextHandle;
}
在plib_twihs_slave_common.h中可以看到需要实现以下几种事件回调。
typedef enum
{
TWIHS_SLAVE_TRANSFER_EVENT_NONE = 0,
/* Address match event */
TWIHS_SLAVE_TRANSFER_EVENT_ADDR_MATCH,
/* Data sent by I2C Master is available */
TWIHS_SLAVE_TRANSFER_EVENT_RX_READY,
/* I2C slave can respond to data read request from I2C Master */
TWIHS_SLAVE_TRANSFER_EVENT_TX_READY,
/* I2C stop condition received or start condtion with other slave address detected */
TWIHS_SLAVE_TRANSFER_EVENT_TRANSMISSION_COMPLETE,
}TWIHS_SLAVE_TRANSFER_EVENT;
typedef bool (*TWIHS_SLAVE_CALLBACK) ( TWIHS_SLAVE_TRANSFER_EVENT event, uintptr_t contextHandle );
从机回调函数实现
手动实现的回调函数如下,只是简单实现接收和发送功能:
bool TWIHS2_SlaveCallback(TWIHS_SLAVE_TRANSFER_EVENT event, uintptr_t context)
{
(void)context;
switch (event)
{
case TWIHS_SLAVE_TRANSFER_EVENT_ADDR_MATCH:
reg_idx = 0;
break;
case TWIHS_SLAVE_TRANSFER_EVENT_RX_READY:
{
uint8_t data = TWIHS2_ReadByte();
read_buffer[reg_idx] = data;
if (++reg_idx >= I2C_SLAVE_BUFFER_SIZE)
reg_idx = 0;
break;
}
case TWIHS_SLAVE_TRANSFER_EVENT_TX_READY:
TWIHS2_WriteByte(read_buffer[reg_idx]);
if (++reg_idx >= I2C_SLAVE_BUFFER_SIZE)
reg_idx = 0;
break;
case TWIHS_SLAVE_TRANSFER_EVENT_TRANSMISSION_COMPLETE:
break;
default:
break;
}
return true;
}
在STM32中对从机先写后读,核心代码如下:
uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05};
uint8_t rd_data[5];
HAL_I2C_Master_Transmit(&hi2c1, 0x54 << 1, data, 5, 1000);
HAL_I2C_Master_Receive(&hi2c1, 0x54 << 1, rd_data, 5, 1000);
STM32调试可以抓取到读到的数据如下:
同时可以使用逻辑分析仪抓取数据,效果如下:
SPI
SPI协议简要回顾

由CPOL和CPHA组成四种模式:

使用图形界面使能SPI外设,界面如下:
拉低CS->写数据->拉高CS,代码如下:
uint8_t hello_str[] = "hello from the SAM E70 X PLAINED ultra";
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
printf("%s at %s %s\r\n", hello_str, __DATE__, __TIME__);
EXT1_SPI_CS_Clear();
SPI0_Write(hello_str, sizeof(hello_str));
while(SPI0_IsTransmitterBusy());
EXT1_SPI_CS_Set();
while ( true )
{
LED3_Toggle();
SYSTICK_DelayMs(500);
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
使用逻辑分析仪抓取数据,效果如下:
SPI我们使用的是模式0(CPOL=0,CPHA=0),放大后波形如下:
PWM
脉冲宽度调制(Pulse Width Modulation,PWM),使用图形界面配置如下,这里初始占空比设置为50%。
在main函数中使能输出,代码如下:
uint8_t hello_str[] = "hello from the SAM E70 X PLAINED ultra";
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
printf("%s at %s %s\r\n", hello_str, __DATE__, __TIME__);
PWM0_ChannelsStart(PWM_CHANNEL_0_MASK);
while ( true )
{
LED3_Toggle();
SYSTICK_DelayMs(500);
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
使用逻辑分析仪抓取波形,数据如下:
修改占空比为75%,代码如下:
uint8_t hello_str[] = "hello from the SAM E70 X PLAINED ultra";
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
printf("%s at %s %s\r\n", hello_str, __DATE__, __TIME__);
PWM0_REGS->PWM_CH_NUM[0].PWM_CDTY = PWM0_ChannelPeriodGet(PWM_CHANNEL_0) / 4 * 3;
PWM0_ChannelsStart(PWM_CHANNEL_0_MASK);
while ( true )
{
LED3_Toggle();
SYSTICK_DelayMs(500);
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
使用逻辑分析仪抓取波形,数据如下:
本篇简单学习了IIC主机、从机、SPI主机的基本使用,中断,DMA传输等暂未设计,感兴趣可以自行添加测试。接下来将开始学习对存储单元的操作(读写Flash)等。
更多推荐
所有评论(0)