中级会员
 
- 积分
- 303
- 金钱
- 303
- 注册时间
- 2016-5-9
- 在线时间
- 70 小时
|
7金钱
[mw_shl_code=applescript,true]救命啊啊啊啊啊啊!!!我一开始用硬件SPI口来通讯,发现无论想读取哪个地址都只读到0xff,然后写数据写不进!!!!!!!!
#include <stm32f10x.h>
#include "ATT7022.h"
#include "delay.h"
/******************
测量的数据:
交流切入状态
1路A/B/C/相电压、
1路A/B/C/相频率、
1路A/B/C/相电流、
1路A/B/C/相视在功率、
1路A/B/C/相有功功率、
1路A/B/C/相无功功率、
2路A/B/C/相电压、
2路A/B/C/相频率、
2路A/B/C/相电流、
2路A/B/C/相视在功率、
2路A/B/C/相有功功率、
2路A/B/C/相无功功率、
*******************/
void CD4053_Choose0(void);//C/B/A均为0,2(VB2)、3(VC1)、13(VA1)输出
void CD4053_Choose7(void);//C/B/A均为1,1(VB1)、5(VC2)、12(VA2)输出
u8 AC_Cut_State(void);//交流切入状态
void SPI2_WriteByte(u8 Data);//TxData:要写入的字节
u8 SPI2_ReadByte(void);//返回值:读取到的字节
// void Read_ATT_AData(void); //读取A相寄存器数据
// void Read_ATT_BData(void); //读取B相寄存器数据
// void Read_ATT_CData(void); //读取C相寄存器数据
// float Read_Freq(u8 Freq_addr);//读取线频率
// u8 Read_StateFlag(u8 EMUState_addr);//读取状态标志
#define r_Pa 0x01 //有功功率寄存器地址
#define r_Pb 0x02
#define r_Pc 0x03
#define r_Qa 0x05 //无功功率寄存器地址
#define r_Qb 0x06
#define r_Qc 0x07
#define r_Sa 0x09 //视在功率地址
#define r_Sb 0x0A
#define r_Sc 0x0B
#define r_UaRms 0x29 //电压有效寄存器地址
#define r_UbRms 0x48
#define r_UcRms 0x49
#define r_IaRms 0x4A //电流有效寄存器地址
#define r_IbRms 0x4B
#define r_IcRms 0x4C
#define r_Freq 0x1C //线频率寄存器地址
#define r_EMUState 0x2C//状态标志寄存器地址
#define ATT7022_CS_EN GPIO_ResetBits(GPIOC,GPIO_Pin_6)//PC6--CS-低; //PC6拉低
#define ATT7022_CS_DIS GPIO_SetBits(GPIOC,GPIO_Pin_6) //PC6拉高
u32 AC_unit_Data[37];//交流数据寄存器
/*硬件连接:
PC6---------------SPI_CS---->CS1
PB15/SPI2_MOSI---SPI_DIN---->D_DIN
PB14/SPI2_MISO---SPI_OUT---->D_OUT1
PB13/SPI2_CLK-----SPI_CLK--->CLK1
************************************************************************/
void ATT7022_SPI_Init(void)//
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PB时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //PC时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //SPI2时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;//PB14/SPI2_MISO---ATT_SPI_OUT
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_6); //PC6--CS-默认拉高
SPI_Cmd(SPI2, DISABLE); //先禁能,再改变MODE
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置 SPI 全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置 SPI 工作模式:设置为主 SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8 位帧结构
//上升沿放数据,下降沿取数据。SCLK上升沿时将ATT7022E寄存器中的数据放置于DOUT上输出,
//SCLK下降沿时将DIN上的数据采样到ATT7022E中,MSB在前, LSB在后。
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low ; //选择了串行时钟的稳态:低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第2个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS 信号由软件管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频 256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE); //使能 SPI 外设
SPI2_WriteByte(0xff);//启动传输
// ATT7022_Adjust();//校表函数
}
/*************底层接口发送接收函数**********************/
void SPI2_WriteByte(u8 Data)//TxData:要写入的字节
{
u16 retry=0; //防止SPI出现故障通讯卡死
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>0XFFFE)
return;//超时退出
}
SPI2->DR=Data; //发送一个byte
}
//读的时候要注意一个问题,因为从模式是没法提供时钟的,所以主模式下必须要在接收的同时提供时钟。
// 办法就是发送一个字节来实现,发送一个字节就意味着收到一个字节,只要把读出来的字节保存即可
u8 SPI2_ReadByte(void)//返回值:读取到的字节
{
u16 retry=0;
SPI2_WriteByte(0xff);//发送的一个字节,为了给从SPI提供8个时钟脉冲
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>0XFFFE)
return 0;//超时退出
}
return SPI2->DR;
}
/*****************对SPI_ATT7022的上层读写操作函数*****************/
u32 ATT_SPI_Read(u8 Reg_Adrr)//ATT7022_SPI读操作
{
u32 rtemp;
u8 i,a[3];
ATT7022_CS_EN; //使能ATT7022EU
SPI2_WriteByte(Reg_Adrr);
delay_us(3);//
for(i=0;i<3;i++)
{
a=SPI2_ReadByte();
}
rtemp=a[0];
rtemp=(rtemp<<8)+a[1];
rtemp=(rtemp<<8)+a[2];
ATT7022_CS_DIS;
return rtemp;
}
void ATT_SPI_Write(u8 Reg_Adrr,u32 Data)//ATT7022_SPI写操作
{
u8 i;
u8 b[3];
ATT7022_CS_EN;
b[0]=Data>>16;
b[1]=Data>>8;
b[2]=Data;
SPI2_WriteByte(Reg_Adrr);
for(i=0;i<3;i++)
{
SPI2_WriteByte(b);
}
ATT7022_CS_DIS;
}
我调试不出来,然后只能换种方法,我用了模拟SPI的方法来读写,发现只能读取到00,然后数据也写不进去,到底怎么回事
????快疯了!!!!!
#include <stm32f10x.h>
#include "rs485.h"
#include "delay.h"
#define ATT_CS_SET GPIO_SetBits(GPIOC,GPIO_Pin_6) //PC6--CS-高
#define ATT_CS_RESET GPIO_ResetBits(GPIOC,GPIO_Pin_6)//PC6--CS-低
#define ATT_CLK_SET GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define ATT_CLK_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_13)
// #define ATT_DOUT GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1
// #define ATT_DIN_SET GPIO_SetBits(GPIOB,GPIO_Pin_15)
// #define ATT_DIN_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_15)
#define ATT_DIN GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1
#define ATT_DOUT_SET GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define ATT_DOUT_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_15)
void att7022_io_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PB时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //PC时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;//PB14/SPI2_MISO---ATT_SPI_OUT
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ATT_CLK_RESET;//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PB15/SPI2_MOSI---ATT_SPI_DIN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//PC6--CS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
u32 SPI_ATT_Read(u8 adrr)
{
u8 i;
u32 temp=0;
ATT_CS_SET;
ATT_CLK_RESET;
ATT_CS_RESET; //片选为低,开始操作
for(i=0;i<8;i++)
{
ATT_CLK_SET;
delay_us(3);
if(adrr&0x80)
ATT_DOUT_SET;
else
ATT_DOUT_RESET;
delay_us(3);
ATT_CLK_RESET;
delay_us(3);
adrr<<=1;
}
delay_us(3);
for(i=0;i<24;i++)
{
temp<<=1;
ATT_CLK_SET;
delay_us(3);
if(ATT_DIN)
temp|=ATT_DIN;
ATT_CLK_RESET;
delay_us(3);
}
ATT_CS_SET;
return (temp);
}
void SPI_ATT_Write(u8 com_add,u32 data2)
{
u8 i,data1;
data1=0x80|com_add;
ATT_CS_SET;
ATT_CLK_RESET;
ATT_CS_RESET; //片选为低,开始操作
for(i=0;i<8;i++)
{
ATT_CLK_SET;
delay_us(3);
if(data1&0x80)
ATT_DOUT_SET;
else
ATT_DOUT_RESET;
delay_us(3);
ATT_CLK_RESET;
delay_us(3);
data1<<=1; //左移数据
}
for(i=0;i<24;i++)
{
ATT_CLK_SET;
delay_us(3);
if(data2&0x00800000)
ATT_DOUT_SET;
else
ATT_DOUT_RESET;
delay_us(3);
data2<<=1;
ATT_CLK_RESET;
}
ATT_CS_SET;
}[/mw_shl_code] |
|