根据ADI和美信提供的芯片,来实现一些特殊的功能。
一、项目介绍
此次,我参加的是Fastbond主题一,智能可穿戴系列,记录人们行走的里程。使用了美信的MAX32660、MAX1555、MAX887,和ADI的ADXL362,芯片MAX32660作为主控器,接受ADXL发送和处理的信号和在OLED屏幕上显示出对应的数据、芯片MAX1555是作为锂电池的充电器、芯片MAX887作为锂电池给MAX32660供电的降压模块。
二、项目用到的板卡、芯片、模块、仪器、设备等介绍
用到的板卡:MAX32660-EVSYS#、SEN-11446、
用到的芯片:MAX32660、ADXL362、MAX1555、MAX887
用到的模块:主控模块、加速度传感器模块、电源模块、降压模块
用到的仪器:示波器
用到的设备:Keil、AD
三、关键性代码及说明
unsigned int Max_3(unsigned int Number_1,unsigned int Number_2,unsigned int Number_3)
{
unsigned int Max;
if(Number_1>=Number_2&&Number_1>=Number_3)
Max=Number_1;
else if(Number_2>=Number_1&&Number_2>=Number_3)
Max=Number_2;
else
Max=Number_3;
return Max;
}
此函数用来比较三轴检测到的数值大小,并返回那个最大值。
int I2C_Init(mxc_i2c_regs_t *i2c, i2c_speed_t i2cspeed, const sys_cfg_i2c_t* sys_cfg)
{
int err;
int idx = MXC_I2C_GET_IDX(i2c);
// Check the base pointer
MXC_ASSERT(idx >= 0);
// Set system level configurations
if ((err = SYS_I2C_Init(i2c, sys_cfg)) != E_NO_ERROR) {
return err;
}
// Always disable the HW autoflush on data NACK and let the SW handle the flushing.
i2c->tx_ctrl0 |= 0x20;
states[idx].num_wr = 0;
i2c->ctrl = 0; // clear configuration bits
i2c->ctrl = MXC_F_I2C_CTRL_I2C_EN; // Enable I2C
i2c->master_ctrl = 0; // clear master configuration bits
i2c->status = 0; // clear status bits
/* If either SDA or SCL is already low, there is a problem.
* Try reclaiming the bus by sending clocks until we have control of the SDA line.
* Follow procedure defined in i2c spec.
*/
if ((i2c->ctrl & (MXC_F_I2C_CTRL_SCL | MXC_F_I2C_CTRL_SDA)) !=
(MXC_F_I2C_CTRL_SCL | MXC_F_I2C_CTRL_SDA)) {
int i, have_control;
// Set SCL/SDA as software controlled.
i2c->ctrl |= MXC_F_I2C_CTRL_SW_OUT_EN;
// Try to get control of SDA.
for (i = 0; i < 16; i++) {
have_control = 1;
// Drive SCL low and check its state.
i2c->ctrl &= ~(MXC_F_I2C_CTRL_SCL_OUT);
mxc_delay(MXC_DELAY_USEC(5));
if ((i2c->ctrl & MXC_F_I2C_CTRL_SCL) == MXC_F_I2C_CTRL_SCL) {
have_control = 0;
}
// Drive SDA low and check its state.
i2c->ctrl &= ~(MXC_F_I2C_CTRL_SDA_OUT);
mxc_delay(MXC_DELAY_USEC(5));
if ((i2c->ctrl & MXC_F_I2C_CTRL_SDA) == MXC_F_I2C_CTRL_SDA) {
have_control = 0;
}
// Release SDA and check its state.
i2c->ctrl |= (MXC_F_I2C_CTRL_SDA_OUT);
mxc_delay(MXC_DELAY_USEC(5));
if ((i2c->ctrl & MXC_F_I2C_CTRL_SDA) != MXC_F_I2C_CTRL_SDA) {
have_control = 0;
}
// Release SCL and check its state.
i2c->ctrl |= (MXC_F_I2C_CTRL_SCL_OUT);
mxc_delay(MXC_DELAY_USEC(5));
if ((i2c->ctrl & MXC_F_I2C_CTRL_SCL) != MXC_F_I2C_CTRL_SCL) {
have_control = 0;
}
if (have_control) {
// Issue stop
// Drive SDA low.
i2c->ctrl &= ~(MXC_F_I2C_CTRL_SDA_OUT);
mxc_delay(MXC_DELAY_USEC(5));
// Release SDA.
i2c->ctrl |= (MXC_F_I2C_CTRL_SDA_OUT);
mxc_delay(MXC_DELAY_USEC(5));
break;
}
}
if (!have_control) {
return E_COMM_ERR;
}
}
i2c->ctrl = 0; // clear configuration bits
i2c->ctrl = MXC_F_I2C_CTRL_I2C_EN; // Enable I2C
i2c->master_ctrl = 0; // clear master configuration bits
i2c->status= 0; // clear status bits
// Check for HS mode
if (i2cspeed == I2C_HS_MODE) {
i2c->ctrl |= MXC_F_I2C_CTRL_HS_MODE; // Enable HS mode
}
// Disable and clear interrupts
i2c->int_en0 = 0;
i2c->int_en1 = 0;
i2c->int_fl0 = i2c->int_fl0;
i2c->int_fl1 = i2c->int_fl1;
i2c->timeout = 0x0; // set timeout
i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH; // clear the RX FIFO
i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH; // clear the TX FIFO
return I2C_Setspeed(i2c, i2cspeed);
}
进行MAX32660与OLED屏幕的一个IIC同信初始化。
uint8_t ADXL362_Init(void)
{
SPI_Init(SPI0A, 0 , 5000000);
if(ADXL362RegisterRead(XL362_DEVID_AD)==0XAD)
{
ADXL362RegisterWrite(XL362_FILTER_CTL,0x93);
ADXL362RegisterWrite(XL362_POWER_CTL,0x02);
ADXL362RegisterWrite(XL362_ACT_INACT_CTL,0x3F);
ADXL362RegisterWrite(XL362_INTMAP1,0x90);
ADXL362RegisterWrite(XL362_THRESH_ACT_L,0xFA);
ADXL362RegisterWrite(XL362_THRESH_ACT_H,0x00);
ADXL362RegisterWrite(XL362_TIME_ACT,0x01);
ADXL362RegisterWrite(XL362_THRESH_INACT_L,0x96);
ADXL362RegisterWrite(XL362_THRESH_INACT_H,0x00);
ADXL362RegisterWrite(XL362_TIME_INACT_L,0x1E);
ADXL362RegisterWrite(XL362_TIME_INACT_H,0x00);
return 0;
}
return 1;
}
对ADXL362的一个初始化。
void SysTick_Handler(void)
{
unsigned int i;
num++;
if(num==5)
{
num=0;
for(i=0;i<50;i++)
{
ADXL362_RD_Avval((xf+i),(yf+i),(zf+i));
}
data_pros();
}
}
中断。
void ADXL362_RD_Avval(unsigned int *x,unsigned int *y,unsigned int *z)
{
uint8_t i;
*x=0;
*y=0;
*z=0;
for(i=0;i<9;i++)
{
*(tx+i)=*(tx+i+1);
*(ty+i)=*(ty+i+1);
*(tz+i)=*(tz+i+1);
}
ADXL362RegisterRead6(XL362_XDATA_L,6,(tx+9),(ty+9),(tz+9));
for(i=0;i<10;i++)
{
*x+=tx[i];
*y+=ty[i];
*z+=tz[i];
}
*x=*x/10;
*y=*y/10;
*z=*z/10;
}
读取ADXL362的值。
unsigned int data_pros() //Êý¾Ý´¦Àíº¯Êý
{
unsigned int i,j,t;
unsigned int p,m,n;
unsigned char thread_old_1,thread_old_2,thread_new_1,thread_new_2;
unsigned int thread_old,thread_new=0,thread_x,thread_y,thread_z;
thread_old_1=ADXL362RegisterRead(XL362_THRESH_ACT_L); //¶ÁÈ¡ãÐÖµ
thread_old_2=ADXL362RegisterRead(XL362_THRESH_ACT_H);
thread_old=((uint16_t)thread_old_2<<8)|thread_old_1;
for(i=0;i<50;i++)
{
ADXL362_RD_Avval((xf+i),(yf+i),(zf+i));
// p=*(xf+i);
// m=*(yf+i);
// n=*(zf+i);
//// printf("%d\n" ,xf[i]);
//
}
for(i=0;i<50;i++)
{
if((*(Huge+i)<=thread_old)&&((*(Huge+i-2)>thread_old)||(*(Huge+i-1)>thread_old)))
step+=1;
}
for( i=0;i<50;i++) //ðÅÝ·¨ÅÅÐòµÃµ½ÐµÄ×î´óãÐÖµ
for(j=0;j<50-i;j++)
{
if(*(xf+j)>*(xf+j+1))
{
t=*(xf+j);
*(xf+j)=*(xf+j+1);
*(xf+j+1)=t;
}
}
thread_x=(*(xf+49)-*xf)/2;
for( i=0;i<50;i++)
for(j=0;j<50-i;j++)
{
if(*(yf+j)>*(yf+j+1))
{
t=*(yf+j);
*(yf+j)=*(yf+j+1);
*(yf+j+1)=t;
}
}
thread_y=(*(yf+49)-*yf)/2;
for( i=0;i<50;i++)
for(j=0;j<50-i;j++)
{
if(*(zf+j)>*(zf+j+1))
{
t=*(zf+j);
*(zf+j)=*(zf+j+1);
*(zf+j+1)=t;
}
}
thread_z=(*(zf+49)-*zf)/2;
thread_new=Max_3(thread_x,thread_y,thread_z);
if(thread_new==thread_x)
Huge=xf;
else if(thread_new==thread_y)
Huge=yf;
else
Huge=zf; //ÅжÏãÐÖµÄĸöÖá×î´ó
thread_new_2=(unsigned char)(thread_new>>8);
thread_new_1=(unsigned char)(thread_new&0x00ff);
ADXL362RegisterWrite(XL362_THRESH_ACT_L,thread_new_1); //¸üÐÂãÐÖµ
ADXL362RegisterWrite(XL362_THRESH_ACT_H,thread_new_2);
return thread_new;
}
进行函数的处理。
//ÏÔʾ2¸öÊý×Ö
//x,y :Æðµã×ø±ê
//len :Êý×ÖµÄλÊý
//size:×ÖÌå´óС
//mode:ģʽ 0,Ìî³äģʽ;1,µþ¼Óģʽ
//num:ÊýÖµ(0~4294967295);
void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2)
{
uint8_t t,temp;
uint8_t enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
在屏幕上显示数字。
//ÏÔʾһ¸ö×Ö·ûºÅ´®
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
在OLED上显示字符。
四、功能演示结果及说明
点亮屏幕
正常显示时间,距离
模拟人走路
验证功能完毕,基本正确。能够很好的显示功能和模拟人在走路时功能。
五、对本活动的心得体会
作为一名在校大学生,非常荣幸参加贵公司由硬禾学堂联合Digi-Key共同发布的为期三个半月的“你创意,我买单” 的Fadtbond活动,这次活动让我有了一个很好的成长,也对AD软件,Keil软件更加熟悉了。“千里之行,始于足下”,这次充实的设计锻炼,丰富我们的学识,拓展我们的视野,是人生的一段重要的经历,也是一个重要步骤,对将来走上工作岗位也有着很大帮助。增强了认识问题,分析问题,解决问题的能力。原本以为自己已经学会了一些基础的知识就够用了,可到了设计电路和程序的时候才知道原来自己要学的东西还有很多,以后自己要走的路还很长,不能只安于现状,一定要奋勇直前。人是在不断前进中成长起来的,虽然会有很多坎坷,但总是会有办法解决的。最后,引用一句古诗结束“纸上得来终觉浅,绝知此事要躬行”。最后,由衷的感谢贵公司为我们提供如此宝贵的学习创造机会,谢谢!