本帖最后由 EDL陆 于 2016-2-1 20:06 编辑
首先自己重新设计了PCB,参考网络上多数人使用无线供电的方式,利用变压器原理,给板上芯片供电,但是在加上无线模块之后,压降太厉害,导致芯片不能正常工作,身边也没有对此比较熟悉的人,教训就是不要再自己不熟悉的地方浪费时间,最终决定换一种方案试一下。如图
反面:中间有两个同心圆,一个接电源,一个接地。电源有马达的轴来供给,为了保证充分接触,选择合适的弹簧套在轴上。为了稍微保持平衡一点,地线也由两个弹簧构成,最好选取软一点的弹簧,不能太硬,不然摩擦会太大。可以想象的到,这样的话旋转起来之后,就不会导致供电有问题了。
正面。排插是留给WIFI模块的,两个595芯片,用来控制16个小灯。
侧视图来一张。
安卓不是很会,现学。在源码的基础上加了自己取字模的功能,更换显示信息。将字模有手机端发送到旋转LED然后存放到Flash,保证数据在掉电后不丢失。接下来试着解决杂声和抖动,完善丰富其他功能。
效果图。
安卓端部分代码:
public class MainActivity<Params> extends TabActivity implements
OnClickListener {
InputStream fin3;
int numChinese=0;
int numAscii=0;
int offChi;
int i,j,k,l;
byte[] temp4 = new byte[32];
int[] temp5 = new int[32];
int[] temp6 = new int[32]; //最终想要的字模(纵向取模) 同笔记
int[] hanzi =new int[32*4]; //首先声明4个汉字的空间
// char[] hanzi =new char[32*4]; //首先声明4个汉字的空间
byte[] hanBuf2;
byte[] hanBuf21;
/******************************************************************************/
@Override
public void onClick(View v) {
switch (v.getId()) {
// 启动2个工作线程:发送、接收。!!!??
case R.id.id_btn_connClose:
connectThread();
break;
case R.id.id_btn_send:
sendData();
break;
case R.id.id_btn_clear:
clearData();
break;
}
}
private void sendData() {
String contentSend = edtSend.getText().toString(); //取得输入框字符
int lenthSend = edtSend.getText().length(); //得到输入字符长度
if (printWriter == null || contentSend == null) {
if (printWriter == null) {
showInfo("连接失败!");
return;
}
if (contentSend == null) {
showInfo("内容为空!");
return;
}
}
for(i=0;i<lenthSend;i++) //遍历左右字符
{
char ch=contentSend.charAt(i);
String str=String.valueOf(ch);
try {
byte[] bs = str.getBytes("gb2312"); //得到区位码
if(bs.length<2) //是英文或者符号
{
numAscii++;
fin3 = getResources().openRawResource(R.raw.ascii);
fin3.skip((bs[0]-32)*16);
fin3.read(temp4, 0, 16);
//64, 32, -96, -96, -96, -64, 0, 0, 6, 9, 8, 8, 8, 15, 8, 0
for(j=0;j<16;j++)
{
temp5[j]=temp4[j]&0xFF; //8位无符号
}
for(k=0;k<8;k++)
{
hanzi[k*2]=temp5[k];
hanzi[k*2+1]=temp5[k+8];
}
printWriter.print('A');
printWriter.print((char)(16*3+1));
printWriter.print((char)i); //帧号
for(l=0;l<16;l++)
{
int baiwei=hanzi[l]/100;
printWriter.print(baiwei);
int shiwei=(hanzi[l]%100)/10;
printWriter.print(shiwei);
int gewei=hanzi[l]%10;
printWriter.print(gewei);
}
printWriter.print('B');
printWriter.flush();
Thread.currentThread();
Thread.sleep(1000);//阻断1秒
}
else
{
numChinese++;
int quma=bs[0]&0xff;
int weima=bs[1]&0xff;
offChi = ((quma-176)*94+(weima-161))*32;
fin3 = getResources().openRawResource(R.raw.hzkst2);
fin3.skip(offChi);
fin3.read(temp4, 0, 32);
for(j=0;j<32;j++)
{
temp5[j]=temp4[j]&0xFF; //8位无符号
}
for(k=0;k<16;k++)
{
hanzi[k*2]=temp5[k];
hanzi[k*2+1]=temp5[k+16]; //最终字模
}
printWriter.print('A');
printWriter.print((char)(32*3+1));
printWriter.print((char)i); //帧号
for(l=0;l<32;l++)
{
int baiwei=hanzi[l]/100;
printWriter.print(baiwei);
int shiwei=(hanzi[l]%100)/10;
printWriter.print(shiwei);
int gewei=hanzi[l]%10;
printWriter.print(gewei);
}
printWriter.print('B');
printWriter.flush();
Thread.currentThread();
Thread.sleep(1000);//阻断1秒
}
} catch (Exception e) {
showInfo("字模读取有问题!");
// TODO: handle exception
}
}
//作为结束帧
printWriter.print('A');
printWriter.print((char)(1));
printWriter.print((char)(numChinese*2+numAscii));
printWriter.print('B');
printWriter.flush();
numChinese=0;
numAscii=0;
}
private void clearData() {
edtReceiver.setText("");
showInfo("清除成功!");
}
private void showInfo(String msg) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG ).show();
}
}
取字模相关的主要是sendData函数。
底层部分代码:
#include "includes.h" //包含总头文件
#include "string.h"
uint_8 receiveFlag=0;
uint_8 startFlag;
uint_8 moveFlag;
#define LED_CLK GPIO_MAKE_PIN(GPIOC_IDX,3) //时钟线
#define LED_STB GPIO_MAKE_PIN(GPIOC_IDX,2) //数据锁存线
#define LED_OE GPIO_MAKE_PIN(GPIOC_IDX,1) //使能线
#define LED_R GPIO_MAKE_PIN(GPIOC_IDX,0) //四根红色数据线
uint_8 bittonum(uint_8 a,uint_8 b,uint_8 c)
{
return a*100+b*10+c;
}
void time_delay(uint_32 delay)
{
uint_32 k;
for(k=0;k<delay;k++)
{
}
}
void LED_init()
{
//LED接线初始化:全部定义为输出,同时给出初始电平
gpio_init(LED_CLK, GPIO_OUTPUT,0); //时钟线
gpio_init(LED_STB, GPIO_OUTPUT,0); //数据锁存线
gpio_init(LED_OE, GPIO_OUTPUT,1); //使能线
gpio_init(LED_R, GPIO_OUTPUT,1); //数据线
}
void Write595(uint_8 data_byte)
{
uint_8 l,temp;
temp=0x80;
for (l=0;l<8;l++)
{
//取data_byte字节中的一位,从高位开始,送入595(数据上线)
if ((data_byte&temp)==0)
gpio_set(LED_R,1); //灭 ,即0表示灭
else
gpio_set(LED_R,0); //亮,即1表示亮
//CLK产生上升沿,使数据送到595移位寄存器
gpio_set(LED_CLK,0);
gpio_set(LED_CLK,1);
temp=temp>>1;
}
}
int main(void)
{
uint_8 params[8]={0};
uint_8 ceshizimo[1024];
uint_8 zimo[32];
uint_32 offset;
uint_8 byteNum; //1byteNum=16字节
//1. 声明主函数使用的变量
uint_32 i,j,k;
uint_8 numChinese; //表示接收到汉字的个数,定位flash存储的位置
uint_8 numAscii;
uint_32 mRuncount; //主循环计数器
uint_32 period;
uint_8 duty;
//2. 关总中断
DISABLE_INTERRUPTS;
//3. 初始化外设模块
light_init(RUN_LIGHT_RED,LIGHT_OFF); //初始化蓝灯
light_init(RUN_LIGHT_GREEN,LIGHT_OFF); //初始化蓝灯
uart_init(0, 115200);
uart_init(2, 115200);
flash_init();
pit_init(0,1000000);
enable_pit_int();
// flash_erase(63);
LED_init();
gpio_init(INF_LIGHT, 0, 0);
// uint_8 value=gpio_get(INF_LIGHT);
gpio_enable_int(INF_LIGHT,FALLING_EDGE);
flash_read(62,0,2,¶ms[0]);
if(params[0]==0x0A)
byteNum=params[1];
else
byteNum=8;
numChinese=0;
numAscii=0;
moveFlag=0;
k=0;
startFlag=0;
mRuncount=0; //主循环计数器
uart_send_string(0,"TEST0");
uart_send_string(2,"TEST2");
//5. 使能模块中断
uart_enable_re_int(0);
uart_enable_re_int(2);
//6. 开总中断
ENABLE_INTERRUPTS;
//进入主循环
//主循环开始==================================================================
for(;;)
{
//运行指示灯闪烁-----------------------------------------------
mRuncount++; //主循环次数计数器+1
if (mRuncount >= RUN_COUNTER_MAX) //主循环次数计数器大于设定的宏常数
{
mRuncount=0; //主循环次数计数器清零
light_change(RUN_LIGHT_GREEN); //蓝灯(RUN_LIGHT_BLUE)状态变化
uart_send1(0,'a');
}
if(1 == receiveFlag)
{
//字母或数字
if(uart_recvBuf[1]==49 )
{
//如果是首帧,清flash及相关变量
if(uart_recvBuf[2]==0)
{
numChinese=0;
numAscii=0;
flash_erase(63);
}
for(i=3,j=0;i<51;i=i+3,j++)
{
zimo[j]=bittonum(uart_recvBuf[i]-48,uart_recvBuf[i+1]-48,uart_recvBuf[i+2]-48);
}
offset=numChinese*32+numAscii*16;
flash_write(63,offset,16,zimo); //将字模数据存放到Flash
numAscii++;
uart_send1(0,'Z');
}
//是中文汉字
else if(uart_recvBuf[1]==97 )
{
if(uart_recvBuf[2]==0)
{
numChinese=0;
numAscii=0;
flash_erase(63);
}
for(i=3,j=0;i<99;i=i+3,j++)
{
zimo[j]=bittonum(uart_recvBuf[i]-48,uart_recvBuf[i+1]-48,uart_recvBuf[i+2]-48);
}
offset=numChinese*32+numAscii*16;
flash_write(63,offset,32,zimo); //将字模数据存放到Flash
numChinese++;
uart_send1(0,'H');
}
//结束帧
else
{
flash_erase(62);
byteNum=uart_recvBuf[2];
params[0]=0x0A;
params[1]=byteNum;
flash_write(62,0,2,params); //将字模数据存放到Flash
memcpy(ceshizimo,63*1024,byteNum*16);
uart_send1(0,'W');
}
receiveFlag=0;
}
//以下加入用户程序----------------------------------------------
if(moveFlag==1) //旋转移动
{
k=k+2;
}
for(i=k;i<128*2+k;i=i+2)
{
//先发送的是下半部分,再发上半部分
Write595(ceshizimo[i+1]); //下半部分
Write595(ceshizimo[i]); //上半部分 低位在上
gpio_set(LED_STB,0);
gpio_set(LED_STB,1);
gpio_set(LED_OE, 0);//使能
time_delay(100);
Write595(0x00);
Write595(0x00);
gpio_set(LED_STB,0);
gpio_set(LED_STB,1);
gpio_set(LED_OE, 1);//使能
if(startFlag==1)
{
startFlag=0;
break;
}
}
} //主循环end_for
//主循环结束==========================================================
}
等自己完善好程序在与大家分享。
校园一角,预祝新年快乐!!!
|