一段时间芯慌后国外芯片价格飙升,国内芯片厂突然崛起;乘此机会使用了该芯片做了一批产品,经过一段时间测试芯片稳定性还可以,工作在电磁环境较差的电源监控中没有出现复位死机现象。
关于该国产芯片资料实在是很少,官方对该芯片的pdf 寄存器描述非常简单;
SPI从机驱动程序:
void slave_spiInit(void)
{
__HAL_RCC_SPI_CLK_ENABLE();// enable SPI clk
// SPI GPIO MAP ...
__HAL_AFIO_REMAP_SPI_CS(GPIOB,GPIO_PIN_4);//NSS
__HAL_AFIO_REMAP_SPI_CLK(GPIOB,GPIO_PIN_24);//SCLK
__HAL_AFIO_REMAP_SPI_MOSI(GPIOB,GPIO_PIN_26);//MOSI
__HAL_AFIO_REMAP_SPI_MISO(GPIOB,GPIO_PIN_25);//MISO
WRITE_REG(SPI->CH_CFG,(1<<22));// clear fifo
WRITE_REG(SPI->SPI_CFG,((1<<16)|//1’b1 spi输出一直有驱动,即使没有数据传输
(1<<1)|//1’b1:传输模式 B
(1<<0)));//1’b1 SCK IDLE 时为 1
//补上:
WRITE_REG(SPI->CH_CFG,(SPI_CH_CFG_RXON | SPI_CH_CFG_TXON)); // enable spi
}
void slave_Send(uint32_t *dat, int len)
{
while(len--){
while((READ_REG(SPI->STATUS) & 0x3F)>=32){;}//
WRITE_REG(SPI->TXDATA, (uint32_t)*dat++);
}
}
int slave_Recv(uint32_t *dat,int len)
{
uint32_t rxfifo_count =READ_REG(SPI->STATUS);
rxfifo_count =(rxfifo_count>>6)&0x3f;
rxfifo_count>>=2;
if(rxfifo_count>=len){
for(int i=0;i<rxfifo_count;i++){
*dat++=SPI->RXDATA;
}
}
return rxfifo_count;
}
void main(void)
{
int fifolen =0;
uint8_t fifoDat[32]={0};
slave_spiInit();
do{
fifolen =slave_Recv((uint32_t*)fifoDat,3);// SPI 收发必须是32 bit !
if(fifolen>=3){//3*4byte =12 Byte
slave_Send((uint32_t*)fifoDat,3);
}
}while(1);
}
SPI主机驱动程序:
void master_spiInit(void)
{
__HAL_RCC_SPI_CLK_ENABLE();// enable SPI clk
// SPI GPIO MAP ...
__HAL_AFIO_REMAP_SPI_CS(GPIOB,GPIO_PIN_4);//NSS
__HAL_AFIO_REMAP_SPI_CLK(GPIOB,GPIO_PIN_24);//SCLK
__HAL_AFIO_REMAP_SPI_MOSI(GPIOB,GPIO_PIN_26);//MOSI
__HAL_AFIO_REMAP_SPI_MISO(GPIOB,GPIO_PIN_25);//MISO
SPI->CH_CFG=(1<<22);// clear fifo
SPI->SPI_CFG =(1<<2);//master style
uint32_t div =40000000/(900000*2) - 1;//SPI =900Khz
SPI->CLK_CFG =div;//设置SPI输出时钟
SPI->CH_CFG|=(SPI_CH_CFG_RXON | SPI_CH_CFG_TXON); // enable spi
}
//返回接收长度
int master_SendRecv(uint8_t *rev ,uint8_t *snd ,uint16_t tlen)
{
uint32_t* snd32 ,*rev32 =(uint32_t*)rev;
uint32_t tx_rx_bitlen,clen=tlen ,rlen=tlen;
snd32 =(uint32_t*)snd;
uint16_t fifo_tfree;
SPI->CH_CFG|=(1<<22);// clear fifo
do{
//step 1 ,确定时钟个数
if(tlen>1020){
clen =1020;
tlen-=1020;
}else{
clen=tlen;
tlen =0;
}
tx_rx_bitlen =SPI->CH_CFG;
tx_rx_bitlen&=~((uint32_t)0xffff<<3);
tx_rx_bitlen|=(clen*8)<<3;
SPI->CH_CFG=tx_rx_bitlen ;
//step 2 ,写入数据到SPI
SPI->CH_CFG|=(1<<0);//启动SPi
do{
//step 3 ,写入数据到SPI
fifo_tfree =(32-(SPI->STATUS& 0x3f))/4;//确定fifo 大小
while(fifo_tfree&&clen){
SPI->TXDATA = *snd32++;
clen =(clen>4)?clen-4:0;
fifo_tfree--;
}
//step 4 ,等待SPI空闲
while(SPI->STATUS&(1<<12)){;}
//step 5 ,接收数据
fifo_tfree =((SPI->STATUS>>6)&0x3f)/4;
while(fifo_tfree--){
*rev32++ = SPI->RXDATA;
}
}while(clen>0);
}while(tlen>0);
//step 6 ,接收残余数据
if(rev32!=NULL&&(rlen&0x3)){//未满4byte
*rev32++ = SPI->RXDATA;
}
return rlen;
}
int main(void)
{
uint8_t txbuf[1024],rxbuf[1024];
master_spiInit();
do{
master_SendRecv(rxbuf,txbuf,25);
}while(1);
}
SPI主机驱动波形: