培训文档(Python)

一、基础语法

1.代码块注释
#注释
	#1.使用'#',在行首使用'#'可注释当前行内容。
	'''
	2.使用三引号(三个单引号),可以将引号囊括的内容注释掉,前后引号可不在同一行。
	'''
2.输入函数input()打印函数print()

input()

print()

sum_1=input("enter your sum")
print(sum_1)
sum_2,sum_3,sum_4=input().split()
print(sum_2,sum_3,sum_4)

my_sum = 10
my_str = "Hello, World!"
my_list = [1, 2, 3, 4, 5]
my_dict = {"name": "Alice", "age": 25}
my_bin = bin(10)
my_tuple = (1, 2, 3, 4, 5)
print(my_sum,my_str,my_list,my_dict,my_bin,my_tuple)
print ('%d = %d * %d' % (my_sum^^my_sum,my_sum,my_sum))
'''
输出:10 Hello, World! [1, 2, 3, 4, 5] {'name': 'Alice', 'age': 25} 	0b1010 (1, 2, 3, 4, 5)
'''
print('整数:%d\n浮点数:%.6f\n字符:%c\n字符串:%s'%(10,20.12,'I','ipc17'))
'''
输出:
整数:10
浮点数:20.120000
字符:I
字符串:ipc17
'''
3.格式化函数format()

f"{sum:9.2f}..."

"{}".format(sum)

	#格式化函数format()
	#数字格式
    #保留小数、百分数显示、左对齐、右对齐、居中对齐
    
	# 保留小数位数
	num = 10.12345
	formatted_num = "{:9.2f}".format(num)
	print(formatted_num)  # 输出:10.12
	print(f"{num:9.2f}\n")
    
	# 百分数显示
	percentage = 0.75
	formatted_percentage = "{:10.2%}".format(percentage)
	print(formatted_percentage)  # 输出:75.00%

	# 对齐
	number = 42
	formatted_number = "{:>10}\n{:^10}\n{:<10}".format(number,number,number)
	print(formatted_number)

	text = "Hello"
    formatted_text = "{:>10}\n{:^10}\n{:<10}".format(text,text,text)
	print(formatted_text)

	'''
	    10.12
    10.12

    75.00%
        42
    42    
42        
     Hello
  Hello   
Hello
	'''
4.查看数据类型type()、查看变量地址id()、大小sys.getsizeof()、长度len()(字符串)

type()

id()

sys.getsizeof()

len()

#查看数据类型
	#type()
	str="string"
	print(type(str))# 输出:<class 'str'>
#查看变量地址、大小、长度(字符串)
	import sys
	sum1=10.0
	str1="hello world!"
	print("sum1_id:",id(sum1),"str1_id:",id(str1))
	print("sum1_size:",sys.getsizeof(sum1),"str1_size:",len(str1))
5.行和缩进

学习 Python 与其他语言最大的区别就是,Python 的代码块不使用大括号 {} 来控制类,函数以及其他逻辑判断。而是用缩进来写模块。缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量。

sum_1=int(input("enter your sum: \n"))
print(sum_1)
if sum_1>0:
    print("sum 正数")
if sum_1<0:
    print("sum 负数")
6.条件语句
if 判断条件:
    执行语句……
elif 判断语句:
	执行语句……
else:
    执行语句……
7.运算符
  • 比较运算符
sum_1 = 10
sum_2 = 20

print(sum_1 == sum_2)   # False,sum_1是否等于sum_2
print(sum_1 != sum_2)   # True,sum_1是否不等于sum_2
print(sum_1 > sum_2)    # False,sum_1是否大于sum_2
print(sum_1 < sum_2)    # True,sum_1是否小于sum_2
print(sum_1 >= sum_2)   # False,sum_1是否大于等于sum_2
print(sum_1 <= sum_2)   # True,sum_1是否小于等于sum_2
  • 逻辑运算符andornot
sum_1 = 10
sum_2 = 20
sum_3 = 30


result = (sum_1 > sum_2) and (sum_2 > sum_3)
print(result)  # 输出:False


result = (sum_1 > sum_2) or (sum_2 > sum_3)
print(result)  # 输出:False


result = not (sum_1 > sum_2)
print(result)  # 输出:True
result = not (sum_2 > sum_3)
print(result)  # 输出:True
  • 成员运算符innot in
sum_1 = 10
sum_2 = 20

sum_list = [5, 10, 15, 20]

if sum_1 in sum_list:
    print("sum_1 在 sum_list 中")  # 输出:sum_1 在 sum_list 中
else:
    print("sum_1 不在 sum_list 中")

if sum_2 not in sum_list:
    print("sum_2 不在 sum_list 中")
else:
    print("sum_2 在 sum_list 中")  # 输出:sum_2 在 sum_list 中
  • 身份运算符isnot is
sum_1 = 10
sum_2 = 20

if sum_1 is sum_2:
    print("sum_1 和 sum_2 是同一个对象")
else:
    print("sum_1 和 sum_2 不是同一个对象")  # 输出:sum_1 和 sum_2 不是同一个对象

if sum_1 is not sum_2:
    print("sum_1 和 sum_2 不是同一个对象")  # 输出:sum_1 和 sum_2 不是同一个对象
else:
    print("sum_1 和 sum_2 是同一个对象")
8.循环控制语句
  • break 语句:在语句块执行过程中终止循环,并且跳出整个循环
  • continue 语句:在语句块执行过程中终止当前循环,跳出该次循环,执行下一次循环。
  • pass 语句:pass是空语句,是为了保持程序结构的完整性。
9.循环语句
  • while循环
whlie 条件:
	执行语句
sum_1=1
while True:
    if sum_1%2==0:
        print(sum_1)
    if sum_1==11:
        break
    sum_1+=1


sum_1=1
while sum_1<11:
    if sum_1%2==0:
        print(sum_1)
    sum_1+=1
else:
    print("打印结束")
  • for循环
for i in 0,1,2,3,4,5:
    print(i)
for i in range(6):
    print(i)
for i in 'ipc17':
    print(i)
    
for num in range(10):  # 迭代 10 到 20 (不包含) 之间的数字
   for i in range(2,num): # 根据因子迭代
      if num%i == 0:      # 确定第一个因子
         j=num/i          # 计算第二个因子
         print ('%d = %d * %d' % (num,i,j))
         break            # 跳出当前循环
   else:                  # 循环的 else 部分
      print ('%d 是一个质数' % num)

二、变量

1.变量命名
  • 变量名只能包含字母、数字和下划线。

变量名能以字母或下划线打头,但不能以数字打头。例如,可将变量命名为message_1,但不能将其命名为1_message。

  • 变量名不能包含空格,但能使用下划线来分隔其中的单词。

例如,变量名greeting_message可行,但变量名greeting message会引发错误。

  • 不要将Python关键字和函数名用作变量名。

即不要使用Python保留用于特殊用途的单词。例如print语句。

2.变量类型
  • Numbers(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Dictionary(字典)
定义变量
  • python创建变量不需要指定变量类型,通过给合适的变量名赋值即可
my_sum = 10
my_str = "Hello, World!"
my_list = [1, 2, 3, 4, 5]
my_dict = {"name": "Alice", "age": 25}
my_bin = b'0000 1000'
my_tuple = (1, 2, 3, 4, 5)

my_sum2,my_str2,my_list2=20,"IPC17",[17,17]

print(type(my_sum))  # 输出:<class 'int'>
print(type(my_str))  # 输出:<class 'str'>
print(type(my_list))  # 输出:<class 'list'>
print(type(my_dict))  # 输出:<class 'dict'>
print(type(my_bin))  # 输出:<class 'bytes'>
print(type(my_tuple))  # 输出:<class 'tuple'>

print(my_sum2,my_str2,my_list2)
x4=None 
x5,x6,x7=20,20.0,None
'''None不同于空字符串""或数字0等,它表示一个特殊的空值。当你想要创建一个占位符变量,暂时没有值时,可以使用None。'''

int(long)、float、complex、decimal、fraction

基本的运算
  • 加法 +:将两个数相加。
  • 减法 -:从一个数中减去另一个数。
  • 乘法 *:将两个数相乘。
  • 除法 /:将一个数除以另一个数,得到浮点数结果。
  • 整除 //:将一个数除以另一个数,得到整数结果。
  • 取模 %:计算除法的余数。
  • 幂运算 **:将一个数的值提高到另一个数的幂。
sum_1 = 10
sum_2 = 20
sum_3 = 0

# 简单的赋值运算符
sum_3 = sum_1 + sum_2
print(sum_3)  # 输出:30

# 加法赋值运算符
sum_3 += sum_1
print(sum_3)  # 输出:40

# 减法赋值运算符
sum_3 -= sum_1
print(sum_3)  # 输出:30

# 乘法赋值运算符
sum_3 *= sum_1
print(sum_3)  # 输出:300

# 除法赋值运算符
sum_3 /= sum_1
print(sum_3)  # 输出:30.0

# 取模赋值运算符
sum_3 %= sum_1
print(sum_3)  # 输出:0.0

# 幂赋值运算符
sum_3 **= sum_1
print(sum_3)  # 输出:0.0

# 取整除赋值运算符
sum_3 //= sum_1
print(sum_3)  # 输出:0.0
使用内置的函数进行进制转换。
  1. 十进制转其他进制:
    • 使用bin()函数将十进制数转换为二进制数。
    • 使用oct()函数将十进制数转换为八进制数。
    • 使用hex()函数将十进制数转换为十六进制数。
decimal = 10

binary = bin(decimal)
print(binary)  # 输出:0b1010

octal = oct(decimal)
print(octal)  # 输出:0o12

hexadecimal = hex(decimal)
print(hexadecimal)  # 输出:0xa
  1. 其他进制转十进制:
    • 使用int()函数将二进制、八进制或十六进制字符串转换为十进制数。
    • 若需要转换为float类型需要在转换为int类型之后使用float()函数。
binary = "1010"
decimal = int(binary, 2)
print(decimal)  # 输出:10

octal = "12"
decimal = int(octal, 8)
print(decimal)  # 输出:10

hexadecimal = "a"
decimal = int(hexadecimal, 16)
print(decimal)  # 输出:10

3.位运算符

  • & 运算符用于对两个数的每个对应位执行按位与操作。
  • | 运算符用于对两个数的每个对应位执行按位或操作。
  • ^ 运算符用于对两个数的每个对应位执行按位异或操作。
  • ~ 运算符用于对一个数的每个对应位执行按位取反操作。
  • << 运算符将一个数的二进制表示向左移动指定的位数。
  • >> 运算符将一个数的二进制表示向右移动指定的位数。
sum_1 = 0b00011001   # 二进制表示,前缀'0b'表示二进制
sum_2 = 0b00010010

c = sum_1 & sum_2   # 按位与运算符
print(c)  # 输出:16
print(type(bin(c)))  # 输出:<class 'str'>
print(bin(c)[2:].zfill(8))  # 输出:00010000

c = sum_1 | sum_2   # 按位或运算符
print(bin(c))  # 输出:0b11011

c = sum_1 ^ sum_2   # 按位异或运算符
print(bin(c))  # 输出:0b1011

c = ~sum_1      # 按位取反运算符
print(bin(c))  # 输出:-0b11101110

c = sum_1 << 2  # 左移运算符
print(bin(c))  # 输出:0b1100100

c = sum_1 >> 2  # 右移运算符
print(bin(c))  # 输出:0b11
string
  • str[index]访问字符串中的字符,通过索引获取指定位置的字符。
  • str[start:end]切片操作,获取字符串的子串,包括起始索引 start,但不包括结束索引 end
  • + 连接字符串,使用加号运算符将两个字符串连接在一起。
  • *重复字符串,使用乘号运算符将字符串重复指定次数。
  • len(str) 获取字符串的长度,返回字符串中字符的个数。
  • sub_str in str 搜索子字符串,使用 in 关键字判断一个子字符串是否在另一个字符串中。
  • str.replace(old, new)替换子字符串,将字符串中的指定子字符串 old 替换为另一个子字符串 new
  • str.lower() / str.upper()将字符串转换为小写 / 大写。
  • str.split(separator) 分割字符串,按照指定的分隔符 separator 将字符串分割成多个子字符串,并返回一个列表。
  • str.strip()去除字符串两端的空白字符。
str = "Innovation class 17"

# 访问字符串中的字符
print("\n访问字符串中的字符")
print(str[0])
print(str[-1])

# 切片操作
print("\n切片操作")
print(str[0:9])
print(str[:9])
print(str[9:])

# 连接字符串
print("\n连接字符串")
new_str = str + " is awesome"
print(new_str)

# 获取字符串长度
print("\n获取字符串长度")
print(len(str))

# 搜索子字符串
print("\n搜索子字符串")
print("class" in str)

# 替换子字符串
print("\n替换子字符串")
replaced_str = str.replace("class", "group")
print(replaced_str)

# 字符串大小写转换
print("\n字符串大小写转换")
lowercase_str = str.lower()
uppercase_str = str.upper()
print(lowercase_str)
print(uppercase_str)

# 分割字符串
print("\n分割字符串")
split_str = str.split()
print(split_str)
print(split_str[1].title())

# 重复字符串
print("\n重复字符串")
repeated_str = str * 3
print(repeated_str)
list

​ 列表由一系列按特定顺序排列的元素组成。你可以创建包含字母表中所有字母、数字0~9或所有家庭成员姓名的列表;也可以将任何东西加入列表中,其中的元素之间可以没有任何关系。

  • 创建列表:可以使用方括号 []list() 函数来创建一个列表。
  • 访问列表元素:通过索引访问列表中的单个元素,索引从0开始。
  • 修改列表元素:可以通过索引对列表中的元素进行赋值操作。
  • 添加元素:可以使用 append() 方法将元素添加到列表的末尾。
  • 插入元素:可以使用 insert() 方法在指定位置插入元素。
  • 删除元素:可以使用 del 关键字、pop() 方法或 remove() 方法删除列表中的元素。
  • 切片操作:可以使用切片操作符 : 获取列表的子列表。
  • 连接列表:可以使用 + 运算符将两个列表连接在一起。
  • 重复列表:可以使用 * 运算符将列表重复多次。
  • 获取列表长度:可以使用 len() 函数获取列表的长度。
  • 搜索元素:可以使用 in 关键字判断一个元素是否在列表中。
  • 排序列表:可以使用 sort() 方法对列表进行排序。
  • 反转列表:可以使用 reverse() 方法将列表中的元素反转。
  • 列表浅拷贝:可以使用切片操作符 [:]copy() 方法创建列表的浅拷贝。
  1. 创建列表:可以使用方括号 []list() 函数来创建一个列表。
my_list = [1, 2, 3, 4, 5]  # 使用方括号创建列表
another_list = list(range(1, 6))  # 使用list()函数创建列表
'''
range()函数是Python中用于生成一个整数序列的内置函数。它通常用于循环和迭代操作。
'''
#range(stop):生成一个从0到stop-1的整数序列,默认步长为1。
#range(start, stop):生成一个从start到stop-1的整数序列,默认步长为1。
	print(list(range(2,7)))#输出: [2, 3, 4, 5, 6]
#range(start, stop, step):生成一个从start到stop-1的整数序列,步长为step。
	print(list(range(1,7,2)))##输出: [1, 3, 5]
  1. 访问列表元素:通过索引访问列表中的单个元素,索引从0开始。
my_list = [1, 2, 3, 4, 5]
print(my_list[0])  # 输出:1
print(my_list[-1])  # 输出:5
  1. 修改列表元素:可以通过索引对列表中的元素进行赋值操作。
my_list = [1, 2, 3, 4, 5]
my_list[0] = 10
print(my_list)  # 输出:[10, 2, 3, 4, 5]
  1. 添加元素:可以使用 append() 方法将元素添加到列表的末尾。
my_list = [1, 2, 3, 4, 5]
print(my_list)#输出:[0, 1, 2, 3, 4, 5]
my_list.append(10)
print(my_list)#输出: [0, 1, 2, 3, 4, 5, 10]
  1. 插入元素:可以使用 insert() 方法在指定位置插入元素。
my_list = [1, 2, 3, 4, 5]
my_list.insert(2, -1)  # 在索引2的位置插入元素-1
print(my_list)#输出: [1, 2, -1, 3, 4, 5]
  1. 删除元素:可以使用 del 关键字、pop() 方法或 remove() 方法删除列表中的元素。

    注:remove参数是列表内可能存在的内容,而不是索引。

my_list = [1, 2, 3, 4, 5]
del my_list[0]  # 删除索引为0的元素
print(my_list)  # 输出:[2, 3, 4, 5]

my_list = [1, 2, 3, 4, 5]
my_list.pop(2)  # 移除并返回索引为2的元素
print(my_list)  # 输出:[1, 2, 4, 5]

my_list = [1, 2, 3, 4, 5]
my_list.remove(5)
print(my_list)
try:
    my_list.remove(6)  # 移除第一个匹配到的元素6
except Exception as e:
    print(e)  # 打印错误信息
    print(my_list)  # 输出:[1, 2, 3, 4, 5]
    
try:
    x=10/0
    print(x)
except Exception as e:
    print(e)  # 打印错误信息

Python中常见的异常和错误类型简要说明:

  • BaseException:所有异常的基类。
  • SystemExit:解释器请求退出。
  • KeyboardInterrupt:用户中断执行,通常是输入Ctrl+C
  • Exception:常规错误的基类。
  • StopIteration:迭代器没有更多的值。
  • GeneratorExit:生成器发生异常以通知退出。
  • StandardError:已弃用,不再使用。
  • ArithmeticError:所有数值计算错误的基类。
  • FloatingPointError:浮点计算错误。
  • OverflowError:数值运算超出最大限制。
  • ZeroDivisionError:除(或取模)零(所有数据类型)。
  • AssertionError:断言语句失败。
  • AttributeError:对象没有这个属性。
  • EOFError:没有内建输入,到达EOF标记。
  • EnvironmentError:操作系统错误的基类。
  • IOError:输入/输出操作失败。
  • OSError:操作系统错误。
  • WindowsError:Windows操作系统错误。
  • ImportError:导入模块/对象失败。
  • LookupError:无效数据查询的基类。
  • IndexError:序列中没有此索引(index)。
  • KeyError:映射中没有这个键。
  • MemoryError:内存溢出错误。
  • NameError:未声明/初始化对象(没有属性)。
  • UnboundLocalError:访问未初始化的局部变量。
  • ReferenceError:弱引用(Weak reference)试图访问已经垃圾回收了的对象。
  • RuntimeError:一般的运行时错误。
  • NotImplementedError:尚未实现的方法。
  • SyntaxError:Python语法错误。
  • IndentationError:缩进错误。
  • TabError:Tab和空格混用。
  • SystemError:一般的解释器系统错误。
  • TypeError:对类型无效的操作。
  • ValueError:传入无效的参数。
  • UnicodeError:Unicode相关的错误。
  • UnicodeDecodeError:Unicode解码时的错误。
  • UnicodeEncodeError:Unicode编码时的错误。
  • UnicodeTranslateError:Unicode转换时的错误。
  • Warning:警告的基类。
  • DeprecationWarning:关于被弃用的特性的警告。
  • FutureWarning:关于构造将来语义会有改变的警告。
  • OverflowWarning:旧的关于自动提升为长整型(long)的警告。
  • PendingDeprecationWarning:关于特性将会被废弃的警告。
  • RuntimeWarning:可疑的运行时行为的警告。
  • SyntaxWarning:可疑的语法的警告。
  • UserWarning:用户代码生成的警告。
  1. 切片操作:可以使用切片操作符 : 获取列表的子列表。
my_list = [1, 2, 3, 4, 5]
print(my_list[1:4])  # 输出:[2, 3, 4]
  1. 连接列表:可以使用 + 运算符将两个列表连接在一起。
my_list1 = [1, 2, 3]
my_list2 = [4, 5, 6]
new_list = my_list1 + my_list2
print(new_list)  # 输出:[1, 2, 3, 4, 5, 6]
  1. 重复列表:可以使用 * 运算符将列表重复多次。
my_list = [1, 2, 3, 4, 5]
repeated_list = my_list * 3
print(repeated_list)  # 输出:[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
  1. 获取列表长度:可以使用 len() 函数获取列表的长度。
my_list = [1, 2, 3, 4, 5]
print(len(my_list))  # 输出:5
  1. 搜索元素:可以使用 in 关键字判断一个元素是否在列表中。
my_list = [1, 2, 3, 4, 5]
print(3 in my_list)  # 输出:True
print(7 in my_list)  # 输出:False
  1. 排序列表:可以使用 sort() 方法对列表进行排序。
my_list = [5, 4, 3, 2, 1]
my_list.sort()
print(my_list)
  1. 反转列表:可以使用 reverse() 方法将列表中的元素反转。
my_list = [1, 2, 3, 4, 5]
my_list.reverse()
print(my_list)  
  1. 列表浅拷贝:可以使用切片操作符 [:]copy() 方法创建列表的浅拷贝。
my_list = [1, 2, 3, 4, 5]
new_list = my_list
print(new_list)

another_list = my_list.copy()
print(another_list)
dictionary

Python中的字典(Dictionary)是一种无序、可变的数据类型,它由键(Key)和对应的值(Value)组成。通过键可以访问对应的值。

Python中涉及字典的常见操作和方法:

  1. 创建字典:

    • my_dict = {}:创建一个空字典。
    • my_dict = {'key1': 'value1', 'key2': 'value2'}:创建一个带有初始键值对的字典。
  2. 访问字典元素:

    • value = my_dict[key]:通过键获取对应的值。
    • my_dict.get(key):通过键获取对应的值,若键不存在则返回None。
    • my_dict.get(key, default):通过键获取对应的值,若键不存在则返回指定的默认值。
  3. 修改字典元素:

    • my_dict[key] = value:设置键的值,若键不存在则创建新的键值对。
  4. 删除字典元素:

    • del my_dict[key]:删除指定键的键值对。
    • my_dict.pop(key):删除指定键的键值对,并返回对应的值。
  5. 检查键是否存在:

    • key in my_dict:检查字典中是否存在指定的键。
    • key not in my_dict:检查字典中是否不存在指定的键。
  6. 获取字典长度和清空字典:

    • len(my_dict):获取字典中键值对的数量。
    • my_dict.clear():清空字典,删除所有的键值对。
  7. 获取字典中的键、值和键值对:

    • my_dict.keys():返回字典中所有的键。
    • my_dict.values():返回字典中所有的值。
    • my_dict.items():返回字典中所有的键值对,以元组的形式。
  8. 遍历字典:

    • 使用for循环遍历字典的键:for key in my_dict:
    • 同时遍历字典的键和值:for key, value in my_dict.items():
  9. 其他常用方法:

    • my_dict.copy():创建字典的浅拷贝。
    • my_dict.update(other_dict):将另一个字典中的键值对更新到当前字典中。
my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 访问字典元素
print('\n访问字典元素')
name = my_dict['name']
age = my_dict['age']
city = my_dict['city']
print(name, age, city)  # 输出: Xiaoming 25 chengdu

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 修改字典元素
print('\n修改字典元素')
my_dict['age'] = 26
print(my_dict)  # 输出: {'name': 'Xiaoming', 'age': 26, 'city': 'chengdu'}

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 删除字典元素
print('\n删除字典元素')
del my_dict['city']
print(my_dict)  # 输出: {'name': 'Xiaoming', 'age': 26}

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 检查键是否存在
print('\n检查键是否存在')
if 'name' in my_dict:
    print("Name exists in the dictionary")

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 获取字典长度和清空字典
print('\n获取字典长度和清空字典')
print(len(my_dict))  # 输出: 2
my_dict.clear()
print(my_dict)  # 输出: {}

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 获取字典中的键、值和键值对
print('\n获取字典中的键、值和键值对')
my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
keys = my_dict.keys()
values = my_dict.values()
items = my_dict.items()
print(keys)  # 输出: dict_keys(['name', 'age', 'city'])
print(values)  # 输出: dict_values(['Xiaoming', 25, 'chengdu'])
print(items)  # 输出: dict_items([('name', 'Xiaoming'), ('age', 25), ('city', 'chengdu')])

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 遍历字典
print('\n遍历字典')
for key in my_dict:
    print(key, my_dict[key])

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 使用items()遍历字典的键和值
print('\n使用items()遍历字典的键和值')
for key, value in my_dict.items():
    print(key, value)

my_dict = {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu'}
# 创建字典的浅拷贝和更新字典
print('\n创建字典的浅拷贝和更新字典')
new_dict = my_dict.copy()
new_dict.update({'country': 'China'})
print(new_dict)  # 输出: {'name': 'Xiaoming', 'age': 25, 'city': 'chengdu', 'country': 'China'}

tuple(元组)

​ 元组(tuple)是Python中的一种数据类型,它是一个有序、不可变的序列。元组由使用逗号分隔的一组值组成,通常用圆括号括起来。与列表不同,元组的元素不可被修改。这意味着一旦创建了元组,就无法对其进行增加、删除或修改元素的操作。元组在存储不可变数据时很有用,例如存储一些常量值或者需要保护不被意外修改的数据。

  1. 创建元组:
my_tuple = (1, 2, 3)
  1. 访问元组元素:
print(my_tuple[0])  # 输出: 1
  1. 元组切片:
print(my_tuple[1:3])  # 输出: (2, 3)
  1. 元组拼接:
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
concatenated_tuple = tuple1 + tuple2
print(concatenated_tuple)  # 输出: (1, 2, 3, 4, 5, 6)
  1. 元组重复:
repeated_tuple = my_tuple * 3
print(repeated_tuple)  # 输出: (1, 2, 3, 1, 2, 3, 1, 2, 3)
  1. 元组长度:
print(len(my_tuple))  # 输出: 3
  1. 元组中的最大值和最小值:
my_tuple = (5, 2, 8, 9, 3)
print(max(my_tuple))  # 输出: 9
print(min(my_tuple))  # 输出: 2
  1. 元组的成员运算符:
my_tuple = (1, 2, 3)
print(2 in my_tuple)  # 输出: True
print(4 not in my_tuple)  # 输出: True
  1. 元组的遍历:

    my_tuple = (1, 2, 3)
    for item in my_tuple:
    	print(item)
    
  2. 不可变性

    首先创建了一个元组my_tuple,其中包含了整数元素123。尝试修改元组的第一个元素,但是由于元组的不可变性,会引发TypeError异常。

    为了修改元组中的元素,需要创建一个新的元组。在例子中,我们使用了元组的拼接操作来创建一个新的元组my_tuple,将1替换为4

    在尝试修改元组元素之后,我们打印了新的元组my_tuple,它现在包含了4作为第一个元素。同时,我们使用id()函数打印了元组对象的内存地址,可以看到在修改元组后,新的元组对象的内存地址与原始的元组对象不同。

    my_tuple = (1, 2, 3)
    print(my_tuple)  # 输出: (1, 2, 3)
    print(id(my_tuple))
    
    # 尝试修改元组的元素(会引发TypeError)
    try:
        my_tuple[0] = 4
    except Exception as e:
        print(e)
    
    my_tuple = my_tuple + (1,)
    print(my_tuple)
    print(id(my_tuple))
    
    '''
    输出结果为:
    (1, 2, 3)
    140171130205952
    'tuple' object does not support item assignment
    (1, 2, 3, 1)
    140171130205120
    '''
    

三、函数

1.定义
def 函数名(参数):
	语句块
	return 返回值ABC
def fun_2(sum_1):
    print(sum_1)
    return sum_1+1
2.调用
def fun_2(sum_1):
    print(sum_1)
    return sum_1+1
sum_3=fun_2(10)
print(sum_3)
3.传参
  • 必备参数:必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
  • 关键字参数:使用关键字参数允许函数调用时参数的顺序与声明时不一致
  • 默认参数:调用函数时,默认参数的值如果没有传入,则被认为是默认值
  1. 必备参数:
def add_numbers(a, b):
    result = a + b
    return result

# 调用函数时必须传递两个数字
sum_result = add_numbers(3, 5)
print(sum_result)
  1. 关键字参数:
def multiply_numbers(x, y):
    result = x * y
    return result

# 使用关键字参数传递数字值
product = multiply_numbers(y=4, x=2)
print(product)
  1. 默认参数:
def power_of_number(base, exponent=2):
    result = base ** exponent
    return result

# 如果不提供第二个参数,默认使用指数为2
result1 = power_of_number(3)
print(result1)

# 提供第二个参数,使用提供的指数
result2 = power_of_number(3, 4)
print(result2)
  1. 不定长参数:
def sum_all_numbers(*args):
    total = sum(args)
    return total

# 不定长参数允许传递任意数量的数字
result = sum_all_numbers(1, 2, 3, 4, 5)
print(result)
4.变量作用域

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。

调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。但是,在函数内使用全局变量,需要在变量前添加关键字global

# 全局变量

global_variable = 10

def example_function():

    # 局部变量
    global global_variable
    #global_variable=50
    local_variable = 5

    print(f"局部变量 local_variable 的值: {local_variable}")

    # 访问全局变量

    print(f"{id(global_variable)}全局变量 global_variable 的值: {global_variable}")

    # 修改全局变量

    global_variable = 20

    # 在函数内创建一个新的局部变量,与外部的同名局部变量无关
    local_variable = 15
    print(f"修改后的局部变量 local_variable 的值: {local_variable}")

# 调用函数
print(id(global_variable))
example_function()

# 在函数外部访问全局变量

print(f"{id(global_variable)}在函数外部访问修改后的全局变量 global_variable 的值: {global_variable}")

'''
output:
1617643373072
局部变量 local_variable 的值: 5
1617643373072全局变量 global_variable 的值: 10
修改后的局部变量 local_variable 的值: 15
1617643373392在函数外部访问修改后的全局变量 global_variable 的值: 20
'''

Python 中的变量名是对对象的引用。全局变量是在全局作用域中定义的变量,而局部变量是在函数内部或其他代码块中定义的变量。

当你在函数内部使用 global 关键字声明一个变量时,它指示 Python 在全局作用域中寻找该变量名,并在全局作用域中创建或修改变量。因此,这个过程是通过变量名来认定全局变量的。

在代码中,global_variable 是在全局作用域中定义的。在函数内部,当使用 global global_variable 时,它是为了确保在函数内部使用的 global_variable 是指向全局作用域中的变量,而不是创建一个新的局部变量。

总的来说,Python 中的全局变量是通过变量名来认定的,而不是通过内存地址。变量名是对对象的引用,而对象本身存储在内存中。通过变量名,你可以在任何作用域中引用和操作相同的对象。

5.可更改对象、不可更改对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

  • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

    • string 不可变类型
def update_string(s):
    print(id(s))
    s = s + " World"  # 在原始字符串的基础上添加 " World"
    print(id(s))
    print("Inside update_string:", s)

my_string = "Hello"
print(id(my_string))
print("Before:", my_string)
update_string(my_string)
print(id(my_string))
print("After:", my_string)
  • tuple 不可变类型
def update_tuple(t):
    print(id(my_tuple))
    t = t + (4,)  # 在原始元组中添加元素 4
    print(id(my_tuple))
    print("Inside update_tuple:", t)

my_tuple = (1, 2, 3)
print("Before:", id(my_tuple),my_tuple)
update_tuple(my_tuple)
print("After:",id(my_tuple), my_tuple)
  • number 不可变类型
def update_number(n):
    print(id(n))
    n = n + 1  # 在原始数字的基础上加 1
    print(id(n))
    print("Inside update_number:", n)

my_number = 5
print("Before:", id(my_number),my_number)
update_number(my_number)
print("After:",id(my_number), my_number)
  • list 可变类型
def update_list(lst):
    print(id(lst))
    lst.append(4)  # 在原始列表中添加元素 4
    print(id(lst))
    print("Inside update_list:", lst)

my_list = [1, 2, 3]
print("Before:", id(my_list),my_list)
update_list(my_list)
print("After:", id(my_list),my_list)
  • dict 可变类型
def update_dict(d):
    print(id(d))
    d["key"] = "value"  # 向原始字典中添加键值对
    print(id(d))
    print("Inside update_dict:", d)

my_dict = {"key1": "value1", "key2": "value2"}
print("Before:", id(my_dict),my_dict)
update_dict(my_dict)
print("After:", id(my_dict),my_dict)

四、多线程

并发执行 — Python 3.12.1 文档

在Python中,多线程是一种并发执行的机制,允许程序同时执行多个线程,每个线程独立执行自己的任务。Python提供了threading模块来支持多线程编程。

  1. 创建线程

    使用threading.Thread类可以创建一个新的线程。你需要提供一个可调用对象(通常是函数或方法),作为线程的执行体。

    import threading
    
    def my_function():
        # 线程执行的任务
        print("Thread executing")
    
    # 创建线程
    my_thread = threading.Thread(target=my_function)
    
  2. 启动线程

    使用start()方法启动线程,使其开始执行。

    # 启动线程
    my_thread.start()
    
  3. 等待线程完成

    使用join()方法可以等待线程执行完成。

    # 等待线程完成
    my_thread.join()
    

    线程创建、开启与使用

    threading.Thread()实例化线程时,基本传入参数

    .join()在程序中的作用

    .active_count()的使用

    time模块的初步使用

import threading
import time

def print_numbers():
    for i in range(5):
        time.sleep(1)
        print(f"Thread 1: {i}")

def print_letters():
    for char in 'ABCDE':
        time.sleep(1)
        print(f"Thread 2: {char}")

# 创建两个线程
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

# 启动线程
thread1.start()
thread2.start()
alive_threads = threading.active_count()
print("alive_threads:",alive_threads)
# 等待两个线程执行完成
thread1.join()
thread2.join()
alive_threads = threading.active_count()
print("alive_threads:",alive_threads)
print("Main thread finished")
import threading
import time

def print_numbers():
    for i in range(5):
        time.sleep(1)
        print(f"Thread 1: {i}\n")

def print_letters():
    for char in 'ABCDE':
        time.sleep(1)
        print(f"Thread 2: {char}\n")

# 创建两个线程
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

# 启动线程
thread1.start()
thread2.start()

while True:
    # 等待两个线程执行完成
    #thread1.join()
    #thread2.join()
    alive_threads = threading.active_count()
    if alive_threads>1:
        print("alive_threads:",alive_threads)
    else:
        print("alive_threads:", alive_threads)
        print("Main thread finished")
        break
    time.sleep(1)

在这个例子中,print_numbersprint_letters 两个函数分别在两个线程中执行,它们并发执行,每个线程在循环中休眠1秒,然后输出相应的内容。主线程等待两个线程执行完成后输出 “Main thread finished”。

具有参数传入与返回的线程

在Python中,queue.Queue 是一种可变类型。具体来说,Queue是在 queue 模块中提供的线程安全的队列实现。它是基于Python的列表(List)实现的,因此具有可变性。

.maxsize:获得创建队列长度

.qsize:获得当前队列值的个数

quene_name.put(value):入队

quene_name.get(value):出队

开启线程时传入参数

import threading
import time
from queue import Queue

def print_numbers(n, result_queue):
    for i in range(n):
        time.sleep(1)
        print(f"Thread 1: {i}")

def print_letters(result_queue):
    result = ''
    for char in 'ABCDE':
        time.sleep(1)
        result += char
        print(f"Thread 2: {char}")
    result_queue.put(result)

# 创建队列
result_queue = Queue()

# 创建两个线程,传递参数给第一个线程
thread1 = threading.Thread(target=print_numbers, args=(5, result_queue))
thread2 = threading.Thread(target=print_letters, args=(result_queue,))

# 启动线程
thread1.start()
thread2.start()

# 等待两个线程执行完成
thread1.join()
thread2.join()

# 获取队列中的返回值
result_from_thread2 = result_queue.get()

# 输出结果
print("Result from Thread 2:", result_from_thread2)
print("Main thread finished")

使用队列,在线程中进行参数交换

import threading
import time
from queue import Queue

def producer(q,len_x=5):
    for i in range(len_x):
        time.sleep(1)
        q.put(i)
        print("Produced: {}. Queue Length: {}. Queue Contents: {}\n".format(i, q.qsize(), list(q.queue)))

def consumer(q):
    for _ in range(5):
        time.sleep(1)
        #value = q.get()
        #print("Consumed: {}. Queue Length: {}. Queue Contents: {}\n".format(value, q.qsize(), list(q.queue)))
        print("Queue Length: {}. Queue Contents: {}\n".format( q.qsize(), list(q.queue)))

# 创建队列
my_queue = Queue(5)
print(my_queue.maxsize)
print(type(my_queue))

# 创建生产者线程和消费者线程
producer_thread = threading.Thread(target=producer, args=(my_queue,3))
consumer_thread = threading.Thread(target=consumer, args=(my_queue,))

# 启动线程
producer_thread.start()
consumer_thread.start()

# 等待两个线程执行完成
producer_thread.join()
consumer_thread.join()

# 输出最终队列的长度和内容
print("Final Queue Length: {}. Queue Contents: {}".format(my_queue.qsize(), list(my_queue.queue)))

五、串口通信

PySerial 3.4 documentation

pyserial 是一个用于串口通信的 Python 库,它提供了一组用于串口操作的函数。以下是一些常见的 pyserial 操作和相关函数:

1.导入模块:
import serial
2.实例化串口对象(打开串口):
import serial
ser_X = serial.Serial(port="COM13",
                        baudrate=921600,
                        bytesize=serial.EIGHTBITS,
                        parity=serial.PARITY_NONE,
                        stopbits=serial.STOPBITS_ONE,
                        timeout=0.001
                        )
if ser_X.isOpen():
    print("ser_X is opened")
else:
    print("ser_X is not opened")

ser_X.close()
if ser_X.isOpen():
    print("ser_X is opened")
else:
    print("ser_X is not opened")
  • serial.Serial 构造函数的参数解释如下:
    • port:要打开的串口的名称或编号。在你的代码中,它被设置为 "port"。实际上,你需要用实际的串口名称或编号替换它,例如在 Windows 上可能是 "COM1",在 Linux 上可能是 "/dev/ttyUSB0"

    • baudrate:串口通信设备操作的波特率或每秒位数(bps)。它确定在串行线路上传输比特的速度。在你的代码中,它被设置为 921600 bps。

    • bytesize:这个参数表示数据位的数量。在你的代码中,它被设置为 serial.EIGHTBITS,这意味着每个字符将使用8位数据。

    • parity:奇偶校验是一种用于检测传输数据中错误的方法。serial.PARITY_NONE 表示不执行奇偶校验。

    • stopbits:它表示用于指示帧结束的停止位的数量。serial.STOPBITS_ONE 表示将使用一个停止位。

    • timeout:这是 read 方法等待传入数据的最大时间(以秒为单位)。在你的代码中,它被设置为 0.001 秒,即 1 毫秒。

3.关闭串口:
ser_X.close()
if ser_X.isOpen():
    print("ser_X is opened")
else:
    print("ser_X is not opened")
4.读取数据:
data = ser_X.read(10)  # 读取 10 个字节的数据

除了 ser.read 方法,serial 模块还提供了其他读取数据的方法,其中一些常见的包括:

  1. ser.readline(size=None): 读取一行数据,可指定读取的最大字节数。默认情况下,会读取直到遇到换行符(‘\n’)为止。

  2. ser.readlines(hint=None): 读取多行数据,可指定读取的最大字节数。如果提供了 hint 参数,将读取至少 hint 字节的数据。

  3. ser.read_until(expected=b’\n’, size=None): 读取数据直到遇到指定的终止字符串或达到指定的最大字节数。默认情况下,终止字符串是换行符。

  4. ser.read_all(): 读取所有可用的数据,直到缓冲区为空。

5.写入数据:
ser_X.write(b'Hello, serial!')
6.等待数据到达:
ser_X.timeout = 5  # 设置超时时间为 5 秒
data = ser_X.read_all()  # 等待并读取所有可用的数据
7.清空输入/输出缓冲区:
   ser.reset_input_buffer()  # 清空输入缓冲区
   ser.reset_output_buffer()  # 清空输出缓冲区
8.“通信协议”

struct.pack 是 Python 中用于将数据打包成二进制字节流的函数,通常用于与低级别的二进制数据进行交互:

struct.pack(format, v1, v2, ...)
  • format: 格式字符串,指定了数据的打包方式。格式字符串中的每个字符表示一个数据项的类型和大小。
  • v1, v2, ...: 要打包的值,可以是一个或多个。

格式字符串的常见格式符号包括:

  • b, h, i, q: 字节、短整型、整型、长整型(有符号)。

  • B, H, I, Q: 无符号字节、短整型、整型、长整型。

  • f, d: 单精度浮点数、双精度浮点数。

  • s: 字符串。

  • b: 一个字节(8位)的有符号整数。

  • h: 两个字节(16位)的有符号短整数。

  • i: 四个字节(32位)的有符号整数。

  • q: 八个字节(64位)的有符号长整数。

  • B: 一个字节(8位)的无符号整数。

  • H: 两个字节(16位)的无符号短整数。

  • I: 四个字节(32位)的无符号整数。

  • Q: 八个字节(64位)的无符号长整数。

  • f: 四个字节(32位)的单精度浮点数。

  • d: 八个字节(64位)的双精度浮点数。

  • s: 字符串,位数取决于字符串的长度。

每个格式符号后面可以加数字,表示数据项的重复次数。例如,'3i' 表示三个整数。

struct.pack 返回一个包含打包后的二进制数据的字节对象。

示例:

import struct

# 打包一个整数和一个浮点数
packed_data = struct.pack('!ih', 42, 3.14)

print(packed_data)
# 输出:b'\x00\x00\x00*@\t\x1e\xb8Q\xeb\x85\x1f\x85\xebQ'
import threading
from queue import Queue
import serial
import struct
import time
ser_X = serial.Serial(port="COM102",
                        baudrate=115200,
                        bytesize=serial.EIGHTBITS,
                        parity=serial.PARITY_NONE,
                        stopbits=serial.STOPBITS_ONE,
                        timeout=0.001
                        )
if ser_X.isOpen():
    print("ser_X is opened")
else:
    print("ser_X is not opened")

def send_data(uart_ser, uart_info, data1, data2, flag1, flag2):
    while True:
        # 使用struct.pack进行打包,'!BBHHHH'表示使用大端字节序,格式为两个字节的帧头(0x0a),
        # 一个字节的标志1(flag1),两个字节的data1,一个字节的标志2(flag2),两个字节的data2,最后一个字节的帧尾(0x0b)
        packed_data = struct.pack('!BBHHHHB', 0x0a, flag1, int(data1), flag2, int(data2), 9, 0x0b)
        #print(packed_data)
        uart_ser.write(packed_data)

        if uart_info:
            print(f"Sent: {packed_data} angle: {data1}, depth_value: {data2}")
        time.sleep(1)


def receive_data(uart_ser,Data_queue):
    while True:
        # 读取数据,假设数据长度为8字节
        received_data = uart_ser.readall()

        # 使用struct.unpack解析数据,'!BBHHHHB'与发送端的打包格式保持一致
        print(received_data.decode('utf-8'))
        #print(received_data)
        try:
            unpacked_data = struct.unpack('!BBHHHHB', received_data)
            # 打印解析后的数据
            print(f"Received: {unpacked_data}")
        except Exception as e:
            print(e)

        '''
        #################################################################
        这里对received_data或received_data.decode('utf-8')等操作,
        *1.完成data1, data2, flag1, flag2的解析,规定都需转为int类型
        *2.通过format函数,将data1, data2, flag1, flag2及其自身的type()打印出来
        *3.一次性将data1, data2, flag1, flag2入队
        
        '''
        time.sleep(1)

def data_parse(data_queue):
    while True:
        '''
        #################################################################
        *1.出队一个数
        *2.使用format打印这个数
        避免队列阻塞造成程序卡死,请参考:
        try:
            item = q.get(timeout=5)  # 设置等待时长为5秒
            print(f"Got item: {item}")
        except queue.Empty:
            print("Queue is empty. Timeout reached.")
        '''
        time.sleep(0.1)

Data_queue=Queue(5)
thread_uart_tx=threading.Thread(target=send_data,args=(ser_X,0,1,45,2,255,))
thread_uart_rx=threading.Thread(target=receive_data,args=(ser_X,Data_queue,))
thread_uart_parse=threading.Thread(target=data_parse,args=(Data_queue,))
thread_uart_tx.start()
time.sleep(0.2)
thread_uart_rx.start()
time.sleep(0.2)
thread_uart_parse.start()

while True:
    print("主循环运行中")
    time.sleep(0.8)
    '''
    遇到的所有问题先尝试自己解决
    '''


#include "sys.h"
#include "uart2.h"	
u8 USART2_RX_BUF[USART2_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节,末字节为换行符
u8 USART2_TX_BUF[USART2_REC_LEN];
u16 USART2_RX_STA=0;       //接收状态标记
u16 Data_py=0;
void uart2_init(u32 bound){
   //GPIO端口设置
  	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能串口2时钟,串口1为APB2
 
	//串口2对应引脚复用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); 
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);
	
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //PA2、PA3
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化

   //串口2初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶效验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  	USART_Init(USART2, &USART_InitStructure); //初始化串口2
	
	//串口2 NVIC 配置
  	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//串口2中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启相关中断
	USART_Cmd(USART2, ENABLE);  //使能串口1
}


void USART2_IRQHandler(void)                	//串口2中断服务程序
{
	u8 Res;
	static int i;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d  0x0a结尾)
	{
		USART_ClearFlag(USART2, USART_FLAG_RXNE);
		Res =USART_ReceiveData(USART2);//(USART1->DR);	//读取接收到的数据
		if(Res == 0x0a)                 //判断帧头
			{
				i = 1;
				USART2_RX_BUF[0] = Res;
			}
			else if(Res != 0x0a && Res != 0x0b)  //接收数据
			{
				USART2_RX_BUF[i] = Res;
				i++;
			}
			else if(Res == 0x0b)           //判断帧尾
			{
				int x=1;
				for(x=1;x<11;x++)
				{
					u2_printf("%X\r\n",USART2_RX_BUF[x]);
				}
				u2_printf("0x0a%.2X%.2X%.2X%.2X%.2X0x0b",
				USART2_RX_BUF[1],USART2_RX_BUF[3],
				USART2_RX_BUF[5],USART2_RX_BUF[7],
				USART2_RX_BUF[9]);
			}

	}	
} 
void u2_printf(char* fmt,...)  
{  
	u16 i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)USART2_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)USART2_TX_BUF);		//此次发送数据的长度
	for(j=0;j<i;j++)							//循环发送数据
	{
		while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
		USART_SendData(USART2,USART2_TX_BUF[j]); 
	} 
}

void sendHexData(uint32_t data) {
    uint8_t byte1 = (data >> 16) & 0xFF; // 获取高位字节
    uint8_t byte2 = (data >> 8) & 0xFF;
    uint8_t byte3 = data & 0xFF; // 获取低位字节

    while (!(USART2->SR & USART_SR_TXE)); // 等待发送缓冲区为空
    USART2->DR = byte1; // 发送高位字节
    while (!(USART2->SR & USART_SR_TXE));
    USART2->DR = byte2;
    while (!(USART2->SR & USART_SR_TXE));
    USART2->DR = byte3; // 发送低位字节
}

void sendHexData8(uint8_t data) {
    while (!(USART2->SR & USART_SR_TXE)); // 等待发送缓冲区为空
    USART2->DR = data; // 将数据写入发送寄存器
}

2, ENABLE); //使能串口1
}

void USART2_IRQHandler(void) //串口2中断服务程序
{
u8 Res;
static int i;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ClearFlag(USART2, USART_FLAG_RXNE);
Res =USART_ReceiveData(USART2);//(USART1->DR); //读取接收到的数据
if(Res == 0x0a) //判断帧头
{
i = 1;
USART2_RX_BUF[0] = Res;
}
else if(Res != 0x0a && Res != 0x0b) //接收数据
{
USART2_RX_BUF[i] = Res;
i++;
}
else if(Res == 0x0b) //判断帧尾
{
int x=1;
for(x=1;x<11;x++)
{
u2_printf(“%X\r\n”,USART2_RX_BUF[x]);
}
u2_printf(“0x0a%.2X%.2X%.2X%.2X%.2X0x0b”,
USART2_RX_BUF[1],USART2_RX_BUF[3],
USART2_RX_BUF[5],USART2_RX_BUF[7],
USART2_RX_BUF[9]);
}

}	

}
void u2_printf(char* fmt,…)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART2_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART2_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART2,USART2_TX_BUF[j]);
}
}

void sendHexData(uint32_t data) {
uint8_t byte1 = (data >> 16) & 0xFF; // 获取高位字节
uint8_t byte2 = (data >> 8) & 0xFF;
uint8_t byte3 = data & 0xFF; // 获取低位字节

while (!(USART2->SR & USART_SR_TXE)); // 等待发送缓冲区为空
USART2->DR = byte1; // 发送高位字节
while (!(USART2->SR & USART_SR_TXE));
USART2->DR = byte2;
while (!(USART2->SR & USART_SR_TXE));
USART2->DR = byte3; // 发送低位字节

}
void sendHexData8(uint8_t data) {
while (!(USART2->SR & USART_SR_TXE)); // 等待发送缓冲区为空
USART2->DR = data; // 将数据写入发送寄存器
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值