我的常用函数

一、STM32

1.1引脚

1.1.1 HALIO输入输出

void io_init(void)

{
    GPIO_InitTypeDef gpio_init_struct;
    do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0);                                   /* KEY0时钟使能 */
    gpio_init_struct.Pin = GPIO_PIN_12;                       /* KEY0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);           /* KEY0引脚模式设置,上拉输入 */
    gpio_init_struct.Pin = GPIO_PIN_13;                       /* KEY1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);           /* KEY1引脚模式设置,上拉输入 */
    gpio_init_struct.Pin = GPIO_PIN_15;                       /* WKUP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                      /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);           /* WKUP引脚模式设置,下拉输入 */
    gpio_init_struct.Pin = GPIO_PIN_14;                       /* WKUP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP ;                    /* 输出 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;                      /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(GPIOB, &gpio_init_struct);           /* WKUP引脚模式设置,下拉输入 */
}
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15) == 0&&KEY3LAST==1){
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,1);
}KEY3LAST = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15);

1.1.2 标准库库IO输入输出

#define LEDC PCout(13)
void IO_init(){//初始化PA0-15为输出后在main.c中通过移位对PA引脚进行控制
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PB5引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //上拉输入模式
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PB5引脚
}

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO, ENABLE); //使能GPIOB时钟//AFIO必须开启
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//要先开时钟,再重映射;这句表示关闭jtag,使能swd。B23

1.1.3 步进电机

unsigned char motorA[] = {0,0,0,0,0,1,1,1};
unsigned char motorB[] = {0,0,0,1,1,1,0,0};
unsigned char motorC[] = {0,1,1,1,0,0,0,0};
unsigned char motorD[] = {1,1,0,0,0,0,0,1};//步进电机移位控制
void IO_init(){//初始化PA0-15为输出后在main.c中通过移位对PA引脚进行控制
GPIO_InitTypeDef  GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //PB5引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //上拉输入模式
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB5引脚
}

//count=5 times=68(count是转速5正常,times是时长68为一秒)
void mcrun(int count,int times){
unsigned char i=0;
if(count>15)count=15;
if(count<5)count=5;
while(times--){
for(i=0;i<8;i++){
DC1 = ~motorA[i];
DC2 = ~motorB[i];
DC3 = ~motorC[i];
DC4 = ~motorD[i];
delay_ms(count);
}
}
DC1 = 0x00;
DC2 = 0x00;
DC3 = 0x00;
DC4 = 0x00;
}

1.1.4 KEY消抖

if(KEY1==0){
delay_ms(10);
if(KEY1==0){
while(KEY1==0);
}
}

1.2 OLED显示

1.2.1 Sptintf

  1. 头文件
#include "stdio.h"
  1. 变量定义
char tempmaxs[20];
Int tempmax;
  1. 函数
sprintf(tempmaxs,":%d",tempmax);

1.3延迟

1.3.1 SysTick_Config系统中断的微秒延迟

void delay_us(uint32_t nus)
{
  uint32_t tickStart, tickCur, tickCnt;
  uint32_t tickMax = SysTick->LOAD;
  uint32_t udelay_value = (SysTick->LOAD/1000)*nus;
  tickStart = SysTick->VAL;
  while(1)
  {
    tickCur = SysTick->VAL;
    tickCnt = (tickStart < tickCur) ? (tickMax+tickStart-tickCur) : (tickStart-tickCur);
    if (tickCnt > udelay_value)
     break;
  }
}

1.4 ESP01S作为服务器发送(弃用)

//定义存储数据的数组
char temp[100];
//字符串长度计算
char temp2[100];
int str_len(char *str) {
    int len = 0;
    while (*str != '\0') {
        len++;
        str++;
    }
    return len;
}
sprintf(temp,"123:\r\n");//存储指定数据
length= str_len(temp);//计算长度
DEBUG_USARTx = USART1;//使用PA9串口
sprintf(temp2,"AT+CIPSEND=0,%d\r\n",length);//AT发送的格式转换
printf(temp2);//转换后发送AT指令
delay_ms(1000);//等待WIFI应答
delay_ms(1000);
printf(temp);//发送数据

1.4.1 STM32配置ESP01S为客户端模式

1.5串口处理

1.5.1 1a2a3a间隔数据处理

函数长度固定:

//函数输入字符串数组的名称
//自动使用printf发送隔开的数据
void extractNumbers(char* str) {
    int len = strlen(str);
    int i;
    char number[20]; // 假设最长的数字不超过20位
    int numberIndex = 0;
    for (i = 0; i < len; i++) {
        if (str[i] == 'a') {
            number[numberIndex] = '\0'; // 添加字符串结束符
            printf("%s\n", number); // 打印提取出来的数字
            numberIndex = 0; // 重置索引,准备提取下一个数字
        } else {
            number[numberIndex] = str[i];
            numberIndex++;
        }
    }
    // 处理最后一个数字
    number[numberIndex] = '\0';
    printf("%s\n", number);
}

函数长度可以控制:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int* convert_to_int_array(char* str, int num_numbers) {
    int* result = (int*)malloc(num_numbers * sizeof(int));
    char* token;
    char* delim = "a";
    int i = 0;

    token = strtok(str, delim);
    while (token != NULL && i < num_numbers) {
        result[i++] = atoi(token);
        token = strtok(NULL, delim);
    }

    return result;
}
int main() {
    char input_str[] = "123a456a789a1003a1a";
    int num_numbers = 4;

    int* result = convert_to_int_array(input_str, num_numbers);

    for (int i = 0; i < num_numbers; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");

    free(result);
    return 0;
}

1.5.2 接收发送回显

  1. 接收与回显
if(USART_RX_STA&0x8000)
{    
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送的消息为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
Data_Processing(len);//转存函数
USART_RX_STA=0;
}
  1. 转存
uint8_t DataRxbuf[512] = {0};
void Data_Processing(int longth){
unsigned int i=0;
memset(DataRxbuf, 0, sizeof(DataRxbuf));
for(i=0;i<longth;i++){
DataRxbuf[i] = USART_RX_BUF[i];
}
DataRxbuf[longth] = '\0';
}
  1. 发送
printf("\r\n\r\n");//插入换行
printf(&DataRxbuf[0]);//发送函数
printf("\r\n\r\n");//插入换行
printf(DataRxbuf);//发送函数
printf("\r\n\r\n");//插入换行

  1. 全部
if(USART_RX_STA&0x8000)
{    
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送的消息为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
Data_Processing(len);
printf("\r\n\r\n");//插入换行
printf(&DataRxbuf[0]);
printf("\r\n\r\n");//插入换行
printf(DataRxbuf);
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}

1.6 STM32简易版发送APP数据

变量与引用:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
u8 lcd_id[50];

首先使用STM32源码里的文件配置串口,接下使用WIFIINIT配置模块。来使用PRINITF发送数据

void wifinit(){
DEBUG_USARTx = USART2;
  printf("AT+CWMODE=2\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s、
  printf("AT+CWMODE=2\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s
printf("AT+CIPMUX=1\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s
printf("AT+CIPMUX=1\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s
printf("AT+CIPSERVER=1,5000\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s
printf("AT+CIPSERVER=1,5000\r\n");
  delay_ms(1000);  //延时1s
delay_ms(500);  //延时1s
DEBUG_USARTx = USART1;
}
sprintf((char*)lcd_id,"l1:%d l3:%d Temp:%d Humi:%d\r\n",(int)temper,(int)mq2,(int)length,(int)Weight_Shiwu);
lenstring =  strlen((char*)lcd_id);
DEBUG_USARTx = USART2;
sprintf((char*)lcd_id,"AT+CIPSEND=0,%d\r\n",lenstring-1);
printf((char*)lcd_id);
delay_ms(500);
printf("l1:%d l3:%d Temp:%d Humi:%d\r\n",(int)temper,(int)mq2,(int)length,(int)Weight_Shiwu);
DEBUG_USARTx = USART1;

1.7 SG90舵机常用程序

1.7.1 舵机正反转次数限制

u8 sg_flag = 1,angle;
void SG90(i){
if(i==1&&sg_flag==0){
sg_flag=1;
for(angle=5;angle<=50;angle+=5)//从5到175度,步进5度
{
servo_angle(angle);
delay_ms(200);
}
}
else if(i==0&&sg_flag==1){
sg_flag=0;
for(angle=50;angle>=5;angle-=5)//从175到5度,步进5度
{
servo_angle(angle);
delay_ms(200);
}
}
}

  • Android Studio

2.1 线程

2.1.1 类线程重复执行刷新UI

//在114查看后更新mainjava和增加DataTransmission类(类见附录1)

 (1)按键触发线程开启

buttonref.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        runOnUiThread(new Runnable() {//更新UI
            @Override
            public void run() {
                RuntestThread runtestThread = new RuntestThread();
                runtestThread.start();
            }
        });
    }
});
  1. 线程内容
class RuntestThread extends Thread{
        public void run(){
            while (true) {
                try {
                    Thread.sleep(1000); // 线程休眠1秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable()
                {
                    public void run() {
                        // TODO Auto-generated method stub
                        String recv_dataName =  DataTransmission.getInstance().getData();
                        if (recv_dataName!=null)
                        {
                            int num = Integer.parseInt(recv_dataName);
                            if(num == 122){
                                //dengtyp.setText("灯:OPEN");
                            }
                            if(num == 123){
                                //dengtyp.setText("灯:CLOSE");
                            }
                            if(num == 124){
                                //mentpe.setText("门:CLOSE");
                                System.out.println("开门");
                            }
                            if(num == 125){
                                //mentpe.setText("门:OPEN");
                                System.out.println("关门");
                            }
                            if(num == 126){
                               // chuantyp.setText("窗:OPEN");
                                System.out.println("开窗");
                            }
                            if(num == 127){
                                //chuantyp.setText("窗:CLOSE");
                                System.out.println("关窗");
                            }
                        }
                    }

                });
            }
        }
}

2.1.2 UI线程处理STM32数据

数据类型:“a12a13a0a12a15”数据量为5整形
                            String[] parts = recv_dataName.split("a");
                            // 2. 将每个子字符串解析为整数并存储到整型变量中
                            int[] numbers = new int[parts.length];
                            for (int i = 0; i < 6; i++) {//数据对应I为6
                                if (!parts[i].isEmpty()) { // 检查字符串是否为空
                                    numbers[i] = Integer.parseInt(parts[i]); // 解析为整数
                                    System.out.println("Number " + i + ": " + numbers[i]);
                                }
                            }
                            temp = findViewById(R.id.txttemp);
                            humi = findViewById(R.id.txthumi);
                            light = findViewById(R.id.txtlight);
                            fire = findViewById(R.id.txtfire);
                            hcsr = findViewById(R.id.txthcsr);
                            temp.setText(numbers[1]+"℃");//数据最小从1开始计算
                            humi.setText(numbers[2]+"%");
                            light.setText(numbers[3]+"LUX");
                            if(numbers[3] == 1){
                                fire.setText("检测到火焰");
                            }
                            hcsr.setText(numbers[5]+"cm");

2.2 开启网页窗口登录IP

第一步:把下列代码放在public class TicketsActivity extends AppCompatActivity类中

private void initWebView() {
    webView = (WebView) findViewById(R.id.mywebview);
    WebSettings webSettings = webView.getSettings();
    webView.setVerticalScrollBarEnabled(false);
    //设置缓存
    webSettings.setSaveFormData(false);
    webSettings.setSavePassword(false);
    //设置JS支持
    //webSettings.setJavaScriptEnabled(true);
    //设置支持缩放变焦
    webSettings.setBuiltInZoomControls(false);
    //设置是否支持缩放
    webSettings.setSupportZoom(false);
    //设置是否允许JS打开新窗口
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    // 修复一些机型webview无法点击
    webView.requestFocus(View.FOCUS_DOWN);
    webView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_UP:
                    if (!v.hasFocus()) {
                        v.requestFocus();
                    }
                    break;
            }
            return false;
        }
    });
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("http:") || url.startsWith("https:") ) {
                view.loadUrl(url);
                return false;
            }else{
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
            }
        }
    });
}

第二步:在按键中添加以下代码

private WebView webView ;//放在主类中

//WebView在widgets中
initWebView();
WebSettings settings = webView.getSettings();
settings.setUserAgentString("pc/XXX");//添加UA,  “app/XXX”:是与h5商量好的标识,h5确认UA为app/XXX就认为该请求的终端为App
settings.setJavaScriptEnabled(true);
//设置参数
settings.setBuiltInZoomControls(true);
settings.setAppCacheEnabled(true);// 设置缓存
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("http://192.168.30.235/");

//如果出现net:ERR_CLEARTEXT_NOT_PERMITTED

对AndroidManifest.xml文件做修改: 在 <application中添加

android:usesCleartextTraffic="true"

2.3 APP Client发送

按键触发:

     TCPService.sendStr(String.valueOf("led on"));
     Toast.makeText(getApplicationContext(), "已发送", Toast.LENGTH_SHORT).show();

还需要在oncreat中加入:

        cmdReceiver =new cmdReceiver();
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction("com.example.communication.data");
        getApplication().registerReceiver(cmdReceiver,intentFilter);

声明:

public cmdReceiver cmdReceiver;

加入类:

    public class cmdReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            recieveData =intent.getStringExtra("data");   //用于保存接收的数据
            //DataHandle(recieveData);
        }
    }

2.4 GPT布局

请使用linerlayout把上面的元素两两组合起来

2.5 解析空格分隔符数据

public class NumberExtractor {
    public static void main(String[] args) {
        String input = "28 433 26 3704 2020 0";
        int[] extractedNumbers = extractNumbers(input, 6); // 可以根据需要修改第二个参数来控制截取数字的个数
        for (int num : extractedNumbers) {
            System.out.println(num);
        }
    }
    public static int[] extractNumbers(String input, int count) {
        String[] numbers = input.split(" ");
        int[] extractedNumbers = new int[count];
        for (int i = 0; i < count; i++) {
            extractedNumbers[i] = Integer.parseInt(numbers[i]);
        }
        return extractedNumbers;
    }
}

//效果如下所示:

2.6 TCP SERVER发送函数

    public void sendDataToServer(final String data) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OutputStream os = MainActivity.tcp_client_socket.getOutputStream();
                    if (!TextUtils.isEmpty(data)) {
                        os.write(data.getBytes());
                        Looper.prepare();
                        Toast.makeText(getApplicationContext(), "已发送", Toast.LENGTH_SHORT).show();
                        Looper.loop();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

附录1

package com.example.tcpassistant;
public class DataTransmission {
    private static DataTransmission instance;
    private String data;
    private DataTransmission() {}
    public static DataTransmission getInstance() {
        if (instance == null) {
            instance = new DataTransmission();
        }
        return instance;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值