DSP SPI口和串行EEPROM在变频器中的应用
时间:11-27
来源:互联网
点击:
4.2软件设计
4.2.1 TMS320 F240的SPI初始化
上文介绍了F240的SPI模块的功能,配置寄存器串行外设接口工作于主模式,波特率设置为2MHz,初始化程序如下:
void SPIinitial(void)
{ *SPICCR=0xc7; //复位SPI
*SPICTL=0x06; //主模式,使能TALK,禁止SPI中断
*SPISTS=0x00; //清中断标志
*SPIBRR=0x04; //波特率设为SPICLK=SYSCLK/4+1=2MHz,SYSCLK=10MHz
*SPIPC1=0x52; //SPISTE引脚配置成输出引脚,SPICLK被配置成串行时钟的输
//入或输出
*SPIPC2=0x22; //SPISIMO,SPISOMI用作SPI输入输出
*SPICCR=0x47; //上升沿发送,下降沿输入数据锁存,无时延,字符长度为8
}
4.2.2 F240对X5168的读写程序
对EEPROM的读写是设计的重点,以下分别介绍:
一、读操作
a).从EEPROM存储器阵列中读数据时,/CS 首先被拉低以选择器件,向器件传送8位读READ指令(00000011B),接着是16位地址(高位在前)。在读操作码和地址送出后,存储位于在所选地址的存储器中的数据在SO线上被移出,继续提供时钟脉冲可接着读出存储在位于下一个地址的存储器中的数据。每移出一个字节地址自动增加至下一个更高的地址,在达到最高地址时,地址计数器返回到地址$0000,允许读周期无限期地继续。将/CS拉高可终止读操作。参见读EEPROM阵列时序图2。
图2 读EEPROM阵列时序图
以下是读X5168子程序,其中RA_ADDR为存储读出数据的数组的首地址,EEP_ADDR为要读取数据在EEPROM阵列中的地址,N为要读取数据的个数
void READ_X5168(unsigned int * RA_ADDR, unsigned int EEP_ADDR, unsigned int N)
{ unsigned int I,readspibuf1,readspibuf2;
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=READ; /*发送X5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR>>8; /*发送地址高八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR; /*发送地址低八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
for (I=0;I
{ *SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuf1=*SPIBUF; /*读取高位字节*/
readspibuf1=readspibuf1<<8;
*SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuf2=*SPIBUF; /*读取低位字节*/
*(RA_ADDR+I)=readspibuf1+readspibuf2;
}
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
b).读状态寄存器时,首先要拉低/CS 线,以选中器件,接着发送8位的RDSR指令(00000101B),在RDSR操作码发出以后,状态寄存器的内容在SO线上被移出。参见读状态寄存器时序图3。
图3 读状态寄存器时序图
以下是读状态寄存器子程序:
unsigned int RSDR_X5168(void)
{ unsigned int readspibuftrue;
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=RDSR; /*发送x5168的读状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuftrue=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuftrue=*SPIBUF; /*读SPIBUF寄存器,读取状态寄存器*/
return readspibuftrue;
}
二、写操作
a).在试图向器件写入数据前必须首先通过发送WREN指令来设置写使能锁存WEL(见图4)。/CS 先被拉低,接着向器件输入WREN指令(00000110B)。在指令的所有的8位传送完后,/CS 必须被拉高。如果用户在发送完WREN指令后,没有将/CS 拉高而继续写操作则该写操作将被忽略。
图4 写使能时序图
串行EEPROMX5168写使能命令子程序如下:
void WREN_X5168(void) /*写使能*/
{ *SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WREN; /*发送X5168的写使能命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
b).为了向EEPROM存储器阵列写入数据用户接着发送写WRITE 指令(00000010B),跟着是16位地址和被写入的数据。任何不用的地址位都被指令为“0”,写操作最少要用32个时钟,/CS 必须为低并在该操作期间一直保持为低。如果地址计数器达到一页的末端而时钟还在继续,时计数器将返回至该页的首地址,并覆盖任何之前已写入的数据。对于将完成的页面写操作(字节或页面写)而言,在写入的最后一个数据的位0被同时输入后,/CS只能被拉高。如果它在其它任何时候被拉高则不能完成写操作(见图5)。
图5 写EEPROM阵列时序图
以下是写EEPROM阵列子程序,RA_ADDR为存储要写数据数组的首地址,EEP_ADDR为要写入的EEPROM首地址,N要存储数据的个数。
void WRITE_X5168(unsigned int * RA_ADDR, unsigned int EEP_ADDR, unsigned int N)
{ unsigned int I;
WREN_X5168(); /*写使能*/
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WRITE; /*发送x5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR>>8; /*先发送高位地址在发送低位地址*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR; /*先发送高位地址在发送低位地址*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
for (I=0;I
{ *SPIDAT =*(RA_ADDR+I)>>8 ; /*发送数据用数组传送,传送数据高八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT =*(RA_ADDR+I) ; /*发送数据用数组传送,传送数据第八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
}
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
c).为向状态寄存器写数据,在WRSR指令(00000001B)之后应跟随被写入的数据(见图6),数据位0和位1必须为“0”。
图6 写状态寄存器时序图
以下是写状态寄存器子程序:
void WRSR_X5168(unsigned int COM) /*写状态*/
{ WREN_X5168(); /*写使能*/
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WRSR; /*发送X5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=COM; /*STATUS_REG发送状态字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPISTS寄存器,清除SPI INT FLAG 位*/
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
TIMEDEL(5); /*延时1us*/
}
以上子程序实现了DSP对X5168的读写功能,在主程序中调用这些子程序就可实现对X5168的操作。
4.2.1 TMS320 F240的SPI初始化
上文介绍了F240的SPI模块的功能,配置寄存器串行外设接口工作于主模式,波特率设置为2MHz,初始化程序如下:
void SPIinitial(void)
{ *SPICCR=0xc7; //复位SPI
*SPICTL=0x06; //主模式,使能TALK,禁止SPI中断
*SPISTS=0x00; //清中断标志
*SPIBRR=0x04; //波特率设为SPICLK=SYSCLK/4+1=2MHz,SYSCLK=10MHz
*SPIPC1=0x52; //SPISTE引脚配置成输出引脚,SPICLK被配置成串行时钟的输
//入或输出
*SPIPC2=0x22; //SPISIMO,SPISOMI用作SPI输入输出
*SPICCR=0x47; //上升沿发送,下降沿输入数据锁存,无时延,字符长度为8
}
4.2.2 F240对X5168的读写程序
对EEPROM的读写是设计的重点,以下分别介绍:
一、读操作
a).从EEPROM存储器阵列中读数据时,/CS 首先被拉低以选择器件,向器件传送8位读READ指令(00000011B),接着是16位地址(高位在前)。在读操作码和地址送出后,存储位于在所选地址的存储器中的数据在SO线上被移出,继续提供时钟脉冲可接着读出存储在位于下一个地址的存储器中的数据。每移出一个字节地址自动增加至下一个更高的地址,在达到最高地址时,地址计数器返回到地址$0000,允许读周期无限期地继续。将/CS拉高可终止读操作。参见读EEPROM阵列时序图2。
图2 读EEPROM阵列时序图
以下是读X5168子程序,其中RA_ADDR为存储读出数据的数组的首地址,EEP_ADDR为要读取数据在EEPROM阵列中的地址,N为要读取数据的个数
void READ_X5168(unsigned int * RA_ADDR, unsigned int EEP_ADDR, unsigned int N)
{ unsigned int I,readspibuf1,readspibuf2;
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=READ; /*发送X5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR>>8; /*发送地址高八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR; /*发送地址低八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
for (I=0;I
{ *SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuf1=*SPIBUF; /*读取高位字节*/
readspibuf1=readspibuf1<<8;
*SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuf2=*SPIBUF; /*读取低位字节*/
*(RA_ADDR+I)=readspibuf1+readspibuf2;
}
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
b).读状态寄存器时,首先要拉低/CS 线,以选中器件,接着发送8位的RDSR指令(00000101B),在RDSR操作码发出以后,状态寄存器的内容在SO线上被移出。参见读状态寄存器时序图3。
图3 读状态寄存器时序图
以下是读状态寄存器子程序:
unsigned int RSDR_X5168(void)
{ unsigned int readspibuftrue;
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=RDSR; /*发送x5168的读状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuftrue=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=0; /*发送伪数据*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI读/写结束*/
readspibuftrue=*SPIBUF; /*读SPIBUF寄存器,读取状态寄存器*/
return readspibuftrue;
}
二、写操作
a).在试图向器件写入数据前必须首先通过发送WREN指令来设置写使能锁存WEL(见图4)。/CS 先被拉低,接着向器件输入WREN指令(00000110B)。在指令的所有的8位传送完后,/CS 必须被拉高。如果用户在发送完WREN指令后,没有将/CS 拉高而继续写操作则该写操作将被忽略。
图4 写使能时序图
串行EEPROMX5168写使能命令子程序如下:
void WREN_X5168(void) /*写使能*/
{ *SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WREN; /*发送X5168的写使能命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
b).为了向EEPROM存储器阵列写入数据用户接着发送写WRITE 指令(00000010B),跟着是16位地址和被写入的数据。任何不用的地址位都被指令为“0”,写操作最少要用32个时钟,/CS 必须为低并在该操作期间一直保持为低。如果地址计数器达到一页的末端而时钟还在继续,时计数器将返回至该页的首地址,并覆盖任何之前已写入的数据。对于将完成的页面写操作(字节或页面写)而言,在写入的最后一个数据的位0被同时输入后,/CS只能被拉高。如果它在其它任何时候被拉高则不能完成写操作(见图5)。
图5 写EEPROM阵列时序图
以下是写EEPROM阵列子程序,RA_ADDR为存储要写数据数组的首地址,EEP_ADDR为要写入的EEPROM首地址,N要存储数据的个数。
void WRITE_X5168(unsigned int * RA_ADDR, unsigned int EEP_ADDR, unsigned int N)
{ unsigned int I;
WREN_X5168(); /*写使能*/
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WRITE; /*发送x5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR>>8; /*先发送高位地址在发送低位地址*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=EEP_ADDR; /*先发送高位地址在发送低位地址*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
for (I=0;I
{ *SPIDAT =*(RA_ADDR+I)>>8 ; /*发送数据用数组传送,传送数据高八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT =*(RA_ADDR+I) ; /*发送数据用数组传送,传送数据第八位*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
}
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
}
c).为向状态寄存器写数据,在WRSR指令(00000001B)之后应跟随被写入的数据(见图6),数据位0和位1必须为“0”。
图6 写状态寄存器时序图
以下是写状态寄存器子程序:
void WRSR_X5168(unsigned int COM) /*写状态*/
{ WREN_X5168(); /*写使能*/
*SPIPC1&=0xBF; /*置低SPISTE引脚,从而选通X5168*/
*SPIDAT=WRSR; /*发送X5168的写状态寄存器命令字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPIBUF寄存器,清除SPI INT FLAG 位*/
*SPIDAT=COM; /*STATUS_REG发送状态字*/
while((*SPISTS&0x40)!=0x40){} /*等待SPI写结束*/
readspibuf=*SPIBUF; /*读SPISTS寄存器,清除SPI INT FLAG 位*/
*SPIPC1|=0x40; /*置高SPISTE引脚,从而禁止X5168*/
TIMEDEL(5); /*延时1us*/
}
以上子程序实现了DSP对X5168的读写功能,在主程序中调用这些子程序就可实现对X5168的操作。
看门狗 总线 PIC DSP 电压 电路 CMOS 相关文章:
- 单片机与PLC编程的区别(10-18)
- 微处理器超长启动周期中的外部看门狗管理方案(05-27)
- 看门狗管理方案设计及应用汇总(01-14)
- DSP自动加载过程及程序烧写的简化设计(02-24)
- CapsMCU在小家电产品中的应用(04-03)
- 基于Proteus和ADS的ARM虚拟实验室建设(05-12)