📄 main.c
字号:
#define IN_MAIN
#include "config.h"
#pragma import(__use_no_semihosting_swi) //don't delete this line
/*定义SSP配置值*/
#define SSP_TYPE 0 //SPI格式
#define SSP_MODE 1 //主机模式
#define SSP_Fssp 100000 //通信速率100k
#define SSP_INT_En 0 //中断禁止
/*定义SPI配置值*/
#define SPI_MODE 1 //主机模式
#define SPI_Fspi 100000 //通信速率10k
#define SPI_INT_En 0 //中断禁止
/*定义 SSP 的管脚*/
#define SCK1 (2<<28) //时钟线 P0.14
#define MISO1 (1<<6) //主机输入,从机输出 P0.19
#define MOSI1 (1<<8) //主机输出,从机输入 P0.20
#define SSEL1 (1<<10) //片选端口 P0.21
/*定义 SPI 的管脚*/
#define SCK0 (1<<8) // SCK0 为P0.4的第二功能
#define MISO0 (1<<10) // MISO0 为P0.5的第二功能
#define MOSI0 (1<<12) // MOSI0 为P0.6的第二功能
#define SSEL0 (1<<14) // SSEL0 为P0.7的第二功能
#define SPI_CS (1<<8) // SPI片选端口为P0.8
#define DBG 0 // DBG CPHA CPOL
// 0 0 0
// 1 0 1
// 2 1 0
// 3 1 1
/*********************************************************************************************************
** Function name: IRQ_Exception
** Descriptions: interrupt exceptional handler , change it as needed
** don't delete this function
********************************************************************************************************/
void IRQ_Exception(void)
{
}
/*********************************************************************************************************
** 函数名称: SPI_Init()
** 函数功能: 初始化SPI接口。
** 入口参数: MODE SPI模式选择,0--从机,1--主机
** F_spi SPI通信速率,最大为Fpclk/8.该参数在从机模式下是无效的
** INT_En 中断使能位,0--中断禁止,1--中断使能
** 出口参数: 0 初始化失败
** 1 初始化成功
********************************************************************************************************/
uint8 SPI_Init(uint8 MODE,uint32 F_spi,uint8 INT_En)
{
uint8 tmp = 0;
if((MODE != 0)&&(MODE != 1)) return(0);
PINSEL0 = (PINSEL0 & (~(0xff<<8)))|SCK0|MISO0|MOSI0|SSEL0; //设置管脚连接SPI
if(F_spi > (Fpclk/8)) F_spi = Fpclk/8;
SPI_SPCCR = Fpclk/F_spi; //设置SPI时钟分频
#if(DBG == 0)
SPI_SPCR = (0<<3)| //CPHA=0
(0<<4)| //CPOL=0
(MODE<<5)| //MODE=1,设置为主机
(0<<6)| //LSBF=0,数据传输MSB在先
(INT_En<<7); //设置中断使能位
#endif
#if(DBG == 1)
SPI_SPCR = (0<<3)| //CPHA=0
(1<<4)| //CPOL=1
(MODE<<5)| //MODE=1,设置为主机
(0<<6)| //LSBF=0,数据传输MSB在先
(INT_En<<7); //设置中断使能位
#endif
#if(DBG == 2)
SPI_SPCR = (1<<3)| //CPHA=1
(0<<4)| //CPOL=0
(MODE<<5)| //MODE=1,设置为主机
(0<<6)| //LSBF=0,数据传输MSB在先
(INT_En<<7); //设置中断使能位
#endif
#if(DBG == 3)
SPI_SPCR = (1<<3)| //CPHA=1
(1<<4)| //CPOL=1
(MODE<<5)| //MODE=1,设置为主机
(0<<6)| //LSBF=0,数据传输MSB在先
(INT_En<<7); //设置中断使能位
#endif
tmp = S0PSR; //清除SPI传输完成标志
S0PINT = 0x01; //清除SPI中断标志位
return(1);
}
/*********************************************************************************************************
**函数名称:SPI_SendByte()
**函数功能:向SPI总线发送数据
**入口参数:data 待发送的数据
**出口参数:返回值为读取的数据
**说明:调用函数前要先选中SPI从机
********************************************************************************************************/
uint8 SPI_SendByte(uint8 data)
{
SPI_SPDR = data;
while((SPI_SPSR & 0x80) ==0); //等待SPIF置位,即等待数据发送完毕
return(SPI_SPDR);
}
/*********************************************************************************************************
** 函数名称: SSP_Init()
** 函数功能: 初始化SSP控制器。
** 入口参数: Type 通信格式,0--SPI,1--SSI,2--Microwire
** MODE 模式位,1--主机,0--从机
** F_ssp SSP通信速率
** INT_En SSP中断使能控制字节,按位来操作
** bit0--接收溢出中断
** bit1--超时中断
** bit2--Rx FIFO至少有一半为满时,产生中断
** bit3--Tx FIFO至少有一半为空时,产生中断
** 出口参数: 0 初始化失败
** 1 初始化成功
********************************************************************************************************/
uint8 SSP_Init(uint8 Type,uint8 MODE,uint32 F_ssp,uint8 INT_En)
{
if(Type > 2) return(0);
if(MODE > 1) return(0);
//初始化引脚
PINSEL0 = ((PINSEL0 & (~(3<<28)))|SCK1);
PINSEL1 = ((PINSEL1&(~(0x3ff<<6)))|(MISO1|MOSI1|SSEL1));
SSPCR0 = (0x00 << 8)| //SCR 设置SPI时钟分频
(DBG << 6)| //CPHA 时钟输出相位,仅SPI模式有效
(Type << 4)| //FRF 帧格式 00-SPI,01-SSI,10-Microwire,11-保留
(0x07 << 0); //DSS 数据长度,0000~0010-保留 0011-4位 0111-8位 1111-16位
SSPCR1 = (0x00 << 3)| //SOD 从机输出允许
((1-MODE) << 2)| //MS 模式位
(0x01 << 1)| //SSE 使能
(0x00 << 0); //LBM 禁止回写模式
SSPIMSC = INT_En & 0x0f; //中断屏蔽寄存器,4个中断条件都可以产生中断
SSPICR = 0x03; //中断清除寄存器
if(MODE == 0) return(1); //如果是从机,则不必关心通信速率
//设置通信速率
if(F_ssp > (Fpclk/2)) F_ssp = Fpclk/2;
if(F_ssp < (Fpclk/254))
{
SSPCR0 |= (0xff<<8);
if(F_ssp < (Fpclk/(254*256))) F_ssp = Fpclk/(254*256);
SSPCPSR = (Fpclk/(F_ssp*256)); //PCLK分频器
}
else SSPCPSR = (Fpclk/F_ssp); //PCLK分频器
return(1);
}
/*********************************************************************************************************
** 函数名称: SSP_SendByte()
** 函数功能: SSP接口向总线发送1字节数据。
** 入口参数: data 待发送的数据
** 出口参数: 接收到的数据
********************************************************************************************************/
uint8 SSP_SendByte(uint8 data)
{
SSPDR = data;
while((SSPSR & 0x01) == 0); //等待TFE置位,即发送FIFO空
return(SSPDR);
}
/*********************************************************************************************************
** 函数名称: DelayNS()
** 函数功能: 长软件延时。
** 入口参数: dly 延时参数,值越大,延时越久
** 出口参数: 无
********************************************************************************************************/
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
uint8 rcv_data;
/*********************************************************************************************************
** 函数名称:Main()
** 函数功能:比较SSP接口中的SPI格式与SPI硬件接口的区别。
********************************************************************************************************/
void Main(void)
{
TargetInit(VPBDIV_DATA, PLLCFG_DATA, MAMTIM_DATA); // don't delete
while((PLLSTAT & (1 << 10)) == 0); // can delete
PINSEL0 = 0x00000000; //设置I/O连接GPIO
PINSEL1 = 0x00000000;
IO0DIR = SPI_CS;
SSP_Init(SSP_TYPE,SSP_MODE,SSP_Fssp,SSP_INT_En); //初始化SSP接口
SPI_Init(SPI_MODE,SPI_Fspi,SPI_INT_En); //初始化SPI接口
while(1)
{
rcv_data = SSP_SendByte(0xF9); //使用SSP接口发送数据
DelayNS(50);
IO0CLR = SPI_CS;
rcv_data = SPI_SendByte(0xF9); //使用SPI接口发送数据
IO0SET = SPI_CS;
DelayNS(50);
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -